Merge "Fix possible infinite loop when purging textures."
This commit is contained in:
@@ -12,6 +12,8 @@
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include <Caches.h>
|
||||
|
||||
#if 0
|
||||
#define TRACE_BITMAP(code) code
|
||||
#else
|
||||
@@ -251,6 +253,9 @@ static jobject Bitmap_copy(JNIEnv* env, jobject, const SkBitmap* src,
|
||||
}
|
||||
|
||||
static void Bitmap_destructor(JNIEnv* env, jobject, SkBitmap* bitmap) {
|
||||
#ifdef USE_OPENGL_RENDERER
|
||||
android::uirenderer::Caches::getInstance().textureCache.remove(bitmap);
|
||||
#endif
|
||||
delete bitmap;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -86,6 +86,8 @@ private:
|
||||
uint32_t mSize;
|
||||
uint32_t mMaxSize;
|
||||
GLint mMaxTextureSize;
|
||||
|
||||
mutable Mutex mLock;
|
||||
}; // class TextureCache
|
||||
|
||||
}; // namespace uirenderer
|
||||
|
||||
Reference in New Issue
Block a user