diff options
author | Romain Guy <romainguy@google.com> | 2010-09-08 15:15:43 -0700 |
---|---|---|
committer | Romain Guy <romainguy@google.com> | 2010-09-08 15:15:43 -0700 |
commit | 9aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4 (patch) | |
tree | cdb43405ac7ef845d01d993442193cad2adfb84e /libs | |
parent | 53389bdcdf6ffaaec533b73bc1d0abc5807ec7f6 (diff) | |
download | frameworks_base-9aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4.zip frameworks_base-9aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4.tar.gz frameworks_base-9aaa8269a3e7291aab84d01c3fc9c744d8f2d2f4.tar.bz2 |
Fix possible infinite loop when purging textures.
Change-Id: Ib05b398ae03e734da2dab0496df416fed4570b1c
Diffstat (limited to 'libs')
-rw-r--r-- | libs/hwui/GenerationCache.h | 6 | ||||
-rw-r--r-- | libs/hwui/PatchCache.h | 2 | ||||
-rw-r--r-- | libs/hwui/Texture.h | 5 | ||||
-rw-r--r-- | libs/hwui/TextureCache.cpp | 21 | ||||
-rw-r--r-- | libs/hwui/TextureCache.h | 2 |
5 files changed, 26 insertions, 10 deletions
diff --git a/libs/hwui/GenerationCache.h b/libs/hwui/GenerationCache.h index c358c80..c42a5d8 100644 --- a/libs/hwui/GenerationCache.h +++ b/libs/hwui/GenerationCache.h @@ -143,11 +143,7 @@ void GenerationCache<K, V>::put(K key, V value) { } ssize_t index = mCache.indexOfKey(key); - if (index >= 0) { - sp<Entry<K, V> > entry = mCache.valueAt(index); - detachFromCache(entry); - addToCache(entry, key, value); - } else { + if (index < 0) { sp<Entry<K, V> > entry = new Entry<K, V>; addToCache(entry, key, value); } diff --git a/libs/hwui/PatchCache.h b/libs/hwui/PatchCache.h index e874a16..6dad831 100644 --- a/libs/hwui/PatchCache.h +++ b/libs/hwui/PatchCache.h @@ -17,6 +17,8 @@ #ifndef ANDROID_UI_PATCH_CACHE_H #define ANDROID_UI_PATCH_CACHE_H +#include <utils/ResourceTypes.h> + #include "Patch.h" #include "GenerationCache.h" diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h index 90f548b..817f143 100644 --- a/libs/hwui/Texture.h +++ b/libs/hwui/Texture.h @@ -28,6 +28,7 @@ namespace uirenderer { struct Texture { Texture() { cleanup = false; + bitmapSize = 0; } /** @@ -54,6 +55,10 @@ struct Texture { * Indicates whether this texture should be cleaned up after use. */ bool cleanup; + /** + * Optional, size of the original bitmap. + */ + uint32_t bitmapSize; }; // struct Texture class AutoTexture { diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp index 753c544..e558870 100644 --- a/libs/hwui/TextureCache.cpp +++ b/libs/hwui/TextureCache.cpp @@ -18,6 +18,8 @@ #include <GLES2/gl2.h> +#include <utils/threads.h> + #include "TextureCache.h" #include "Properties.h" @@ -49,6 +51,7 @@ TextureCache::TextureCache(uint32_t maxByteSize): } TextureCache::~TextureCache() { + Mutex::Autolock _l(mLock); mCache.clear(); } @@ -64,14 +67,17 @@ void TextureCache::init() { /////////////////////////////////////////////////////////////////////////////// uint32_t TextureCache::getSize() { + Mutex::Autolock _l(mLock); return mSize; } uint32_t TextureCache::getMaxSize() { + Mutex::Autolock _l(mLock); return mMaxSize; } void TextureCache::setMaxSize(uint32_t maxSize) { + Mutex::Autolock _l(mLock); mMaxSize = maxSize; while (mSize > mMaxSize) { mCache.removeOldest(); @@ -83,12 +89,9 @@ void TextureCache::setMaxSize(uint32_t maxSize) { /////////////////////////////////////////////////////////////////////////////// void TextureCache::operator()(SkBitmap*& bitmap, Texture*& texture) { - if (bitmap) { - const uint32_t size = bitmap->rowBytes() * bitmap->height(); - mSize -= size; - } - + // This will be called already locked if (texture) { + mSize -= texture->bitmapSize; glDeleteTextures(1, &texture->id); delete texture; } @@ -99,6 +102,8 @@ void TextureCache::operator()(SkBitmap*& bitmap, Texture*& texture) { /////////////////////////////////////////////////////////////////////////////// Texture* TextureCache::get(SkBitmap* bitmap) { + Mutex::Autolock _l(mLock); + Texture* texture = mCache.get(bitmap); if (!texture) { if (bitmap->width() > mMaxTextureSize || bitmap->height() > mMaxTextureSize) { @@ -115,6 +120,7 @@ Texture* TextureCache::get(SkBitmap* bitmap) { } texture = new Texture; + texture->bitmapSize = size; generateTexture(bitmap, texture, false); if (size < mMaxSize) { @@ -131,15 +137,18 @@ Texture* TextureCache::get(SkBitmap* bitmap) { } void TextureCache::remove(SkBitmap* bitmap) { + Mutex::Autolock _l(mLock); mCache.remove(bitmap); } void TextureCache::clear() { + Mutex::Autolock _l(mLock); mCache.clear(); } void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate) { SkAutoLockPixels alp(*bitmap); + if (!bitmap->readyToDraw()) { LOGE("Cannot generate texture from bitmap"); return; @@ -159,6 +168,7 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege switch (bitmap->getConfig()) { case SkBitmap::kA8_Config: texture->blend = true; + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, bitmap->rowBytesAsPixels(), texture->height, 0, GL_ALPHA, GL_UNSIGNED_BYTE, bitmap->getPixels()); break; @@ -175,6 +185,7 @@ void TextureCache::generateTexture(SkBitmap* bitmap, Texture* texture, bool rege texture->blend = !bitmap->isOpaque(); break; default: + LOGW("Unsupported bitmap config"); break; } diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h index b5e4c7c..847d69c 100644 --- a/libs/hwui/TextureCache.h +++ b/libs/hwui/TextureCache.h @@ -86,6 +86,8 @@ private: uint32_t mSize; uint32_t mMaxSize; GLint mMaxTextureSize; + + mutable Mutex mLock; }; // class TextureCache }; // namespace uirenderer |