diff options
author | John Reck <jreck@google.com> | 2014-04-11 19:15:05 -0700 |
---|---|---|
committer | John Reck <jreck@google.com> | 2014-04-14 13:17:25 -0700 |
commit | 860d155f866cc15a725e7ce03763280987f24901 (patch) | |
tree | 1ade6b4f5c2c0910c088469b95255eb66ce0cb53 /libs/hwui/TextureCache.cpp | |
parent | db8b130a19484cb6018667905e64d42ab793654f (diff) | |
download | frameworks_base-860d155f866cc15a725e7ce03763280987f24901.zip frameworks_base-860d155f866cc15a725e7ce03763280987f24901.tar.gz frameworks_base-860d155f866cc15a725e7ce03763280987f24901.tar.bz2 |
Fix issue with bitmap uploading
Bug: 13912749
Change-Id: Ic23fa1d280118dc93dc2716a4a24cc0bbbdca595
Diffstat (limited to 'libs/hwui/TextureCache.cpp')
-rw-r--r-- | libs/hwui/TextureCache.cpp | 72 |
1 files changed, 59 insertions, 13 deletions
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp index 01d72d1..34e2265 100644 --- a/libs/hwui/TextureCache.cpp +++ b/libs/hwui/TextureCache.cpp @@ -121,29 +121,49 @@ void TextureCache::operator()(const SkBitmap*&, Texture*& texture) { // Caching /////////////////////////////////////////////////////////////////////////////// -Texture* TextureCache::get(const SkBitmap* bitmap) { +void TextureCache::resetMarkInUse() { + LruCache<const SkBitmap*, Texture*>::Iterator iter(mCache); + while (iter.next()) { + iter.value()->isInUse = false; + } +} + +bool TextureCache::canMakeTextureFromBitmap(const SkBitmap* bitmap) { + if (bitmap->width() > mMaxTextureSize || bitmap->height() > mMaxTextureSize) { + ALOGW("Bitmap too large to be uploaded into a texture (%dx%d, max=%dx%d)", + bitmap->width(), bitmap->height(), mMaxTextureSize, mMaxTextureSize); + return false; + } + return true; +} + +// Returns a prepared Texture* that either is already in the cache or can fit +// in the cache (and is thus added to the cache) +Texture* TextureCache::getCachedTexture(const SkBitmap* bitmap) { Texture* texture = mCache.get(bitmap); if (!texture) { - if (bitmap->width() > mMaxTextureSize || bitmap->height() > mMaxTextureSize) { - ALOGW("Bitmap too large to be uploaded into a texture (%dx%d, max=%dx%d)", - bitmap->width(), bitmap->height(), mMaxTextureSize, mMaxTextureSize); + if (!canMakeTextureFromBitmap(bitmap)) { return NULL; } const uint32_t size = bitmap->rowBytes() * bitmap->height(); + bool canCache = size < mMaxSize; // Don't even try to cache a bitmap that's bigger than the cache - if (size < mMaxSize) { - while (mSize + size > mMaxSize) { + while (canCache && mSize + size > mMaxSize) { + Texture* oldest = mCache.peekOldestValue(); + if (oldest && !oldest->isInUse) { mCache.removeOldest(); + } else { + canCache = false; } } - texture = new Texture(); - texture->bitmapSize = size; - generateTexture(bitmap, texture, false); + if (canCache) { + texture = new Texture(); + texture->bitmapSize = size; + generateTexture(bitmap, texture, false); - if (size < mMaxSize) { mSize += size; TEXTURE_LOGD("TextureCache::get: create texture(%p): name, size, mSize = %d, %d, %d", bitmap, texture->id, size, mSize); @@ -151,16 +171,42 @@ Texture* TextureCache::get(const SkBitmap* bitmap) { ALOGD("Texture created, size = %d", size); } mCache.put(bitmap, texture); - } else { - texture->cleanup = true; } - } else if (bitmap->getGenerationID() != texture->generation) { + } else if (!texture->isInUse && bitmap->getGenerationID() != texture->generation) { + // Texture was in the cache but is dirty, re-upload + // TODO: Re-adjust the cache size if the bitmap's dimensions have changed generateTexture(bitmap, texture, true); } return texture; } +bool TextureCache::prefetchAndMarkInUse(const SkBitmap* bitmap) { + Texture* texture = getCachedTexture(bitmap); + if (texture) { + texture->isInUse = true; + } + return texture; +} + +Texture* TextureCache::get(const SkBitmap* bitmap) { + Texture* texture = getCachedTexture(bitmap); + + if (!texture) { + if (!canMakeTextureFromBitmap(bitmap)) { + return NULL; + } + + const uint32_t size = bitmap->rowBytes() * bitmap->height(); + texture = new Texture(); + texture->bitmapSize = size; + generateTexture(bitmap, texture, false); + texture->cleanup = true; + } + + return texture; +} + Texture* TextureCache::getTransient(const SkBitmap* bitmap) { Texture* texture = new Texture(); texture->bitmapSize = bitmap->rowBytes() * bitmap->height(); |