Fix possible infinite loop when purging textures.
Change-Id: Ib05b398ae03e734da2dab0496df416fed4570b1c
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() {
+ Mutex::Autolock _l(mLock);
mCache.clear();
}
@@ -64,14 +67,17 @@
///////////////////////////////////////////////////////////////////////////////
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::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 @@
///////////////////////////////////////////////////////////////////////////////
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 = new Texture;
+ texture->bitmapSize = size;
generateTexture(bitmap, texture, false);
if (size < mMaxSize) {
@@ -131,15 +137,18 @@
}
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 @@
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 @@
texture->blend = !bitmap->isOpaque();
break;
default:
+ LOGW("Unsupported bitmap config");
break;
}