Free resources only from the GL context thread.
Bug #3179882
Resources were freed following garbage collections on a worker thread.
This worker thread had no EGL context, which would cause the renderer
to incorrectly assume that the memory was liberated.
Change-Id: Ifdb51f94ddf42641e8654522787bfac532976c7c
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index 1be6868..ebecebe 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -53,7 +53,6 @@
}
TextureCache::~TextureCache() {
- Mutex::Autolock _l(mLock);
mCache.clear();
}
@@ -71,17 +70,14 @@
///////////////////////////////////////////////////////////////////////////////
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();
@@ -111,9 +107,7 @@
///////////////////////////////////////////////////////////////////////////////
Texture* TextureCache::get(SkBitmap* bitmap) {
- mLock.lock();
Texture* texture = mCache.get(bitmap);
- mLock.unlock();
if (!texture) {
if (bitmap->width() > mMaxTextureSize || bitmap->height() > mMaxTextureSize) {
@@ -124,11 +118,9 @@
const uint32_t size = bitmap->rowBytes() * bitmap->height();
// Don't even try to cache a bitmap that's bigger than the cache
if (size < mMaxSize) {
- mLock.lock();
while (mSize + size > mMaxSize) {
mCache.removeOldest();
}
- mLock.unlock();
}
texture = new Texture;
@@ -136,7 +128,6 @@
generateTexture(bitmap, texture, false);
if (size < mMaxSize) {
- mLock.lock();
mSize += size;
TEXTURE_LOGD("TextureCache::get: create texture(%p): name, size, mSize = %d, %d, %d",
bitmap, texture->id, size, mSize);
@@ -144,7 +135,6 @@
LOGD("Texture created, size = %d", size);
}
mCache.put(bitmap, texture);
- mLock.unlock();
} else {
texture->cleanup = true;
}
@@ -156,12 +146,24 @@
}
void TextureCache::remove(SkBitmap* bitmap) {
- Mutex::Autolock _l(mLock);
mCache.remove(bitmap);
}
-void TextureCache::clear() {
+void TextureCache::removeDeferred(SkBitmap* bitmap) {
Mutex::Autolock _l(mLock);
+ mGarbage.push(bitmap);
+}
+
+void TextureCache::clearGarbage() {
+ Mutex::Autolock _l(mLock);
+ size_t count = mGarbage.size();
+ for (size_t i = 0; i < count; i++) {
+ mCache.remove(mGarbage.itemAt(i));
+ }
+ mGarbage.clear();
+}
+
+void TextureCache::clear() {
mCache.clear();
TEXTURE_LOGD("TextureCache:clear(), miSize = %d", mSize);
}