diff options
| -rw-r--r-- | core/jni/android/graphics/Bitmap.cpp | 4 | ||||
| -rw-r--r-- | core/jni/android/graphics/Path.cpp | 7 | ||||
| -rw-r--r-- | core/jni/android/graphics/Shader.cpp | 6 | ||||
| -rw-r--r-- | include/utils/Singleton.h | 5 | ||||
| -rw-r--r-- | libs/hwui/Caches.h | 4 | ||||
| -rw-r--r-- | libs/hwui/GenerationCache.h | 6 | ||||
| -rw-r--r-- | libs/hwui/GradientCache.cpp | 14 | ||||
| -rw-r--r-- | libs/hwui/GradientCache.h | 6 | ||||
| -rw-r--r-- | libs/hwui/PathCache.cpp | 27 | ||||
| -rw-r--r-- | libs/hwui/PathCache.h | 10 | ||||
| -rw-r--r-- | libs/hwui/TextureCache.cpp | 9 | ||||
| -rw-r--r-- | libs/hwui/TextureCache.h | 4 |
12 files changed, 98 insertions, 4 deletions
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp index 95bb24f..880fb6e 100644 --- a/core/jni/android/graphics/Bitmap.cpp +++ b/core/jni/android/graphics/Bitmap.cpp @@ -254,7 +254,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);
+ if (android::uirenderer::Caches::hasInstance()) {
+ android::uirenderer::Caches::getInstance().textureCache.remove(bitmap);
+ }
#endif
delete bitmap;
}
diff --git a/core/jni/android/graphics/Path.cpp b/core/jni/android/graphics/Path.cpp index b8b2a10..abe33f4 100644 --- a/core/jni/android/graphics/Path.cpp +++ b/core/jni/android/graphics/Path.cpp @@ -26,12 +26,19 @@ #include "SkPath.h" +#include <Caches.h> + namespace android { class SkPathGlue { public: static void finalizer(JNIEnv* env, jobject clazz, SkPath* obj) { +#ifdef USE_OPENGL_RENDERER + if (android::uirenderer::Caches::hasInstance()) { + android::uirenderer::Caches::getInstance().pathCache.remove(obj); + } +#endif delete obj; } diff --git a/core/jni/android/graphics/Shader.cpp b/core/jni/android/graphics/Shader.cpp index cb1c333..9202429 100644 --- a/core/jni/android/graphics/Shader.cpp +++ b/core/jni/android/graphics/Shader.cpp @@ -9,6 +9,7 @@ #include "SkXfermode.h" #include <SkiaShader.h> +#include <Caches.h> using namespace android::uirenderer; @@ -52,6 +53,11 @@ static int Color_HSVToColor(JNIEnv* env, jobject, int alpha, jfloatArray hsvArra static void Shader_destructor(JNIEnv* env, jobject o, SkShader* shader, SkiaShader* skiaShader) { +#ifdef USE_OPENGL_RENDERER + if (android::uirenderer::Caches::hasInstance()) { + android::uirenderer::Caches::getInstance().gradientCache.remove(shader); + } +#endif delete skiaShader; shader->safeUnref(); } diff --git a/include/utils/Singleton.h b/include/utils/Singleton.h index 3b975b4..e1ee8eb 100644 --- a/include/utils/Singleton.h +++ b/include/utils/Singleton.h @@ -37,6 +37,11 @@ public: } return *instance; } + + static bool hasInstance() { + Mutex::Autolock _l(sLock); + return sInstance != 0; + } protected: ~Singleton() { }; diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index fda57b8..9c67885 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -17,7 +17,9 @@ #ifndef ANDROID_UI_CACHES_H #define ANDROID_UI_CACHES_H -#define LOG_TAG "OpenGLRenderer" +#ifndef LOG_TAG + #define LOG_TAG "OpenGLRenderer" +#endif #include <utils/Singleton.h> diff --git a/libs/hwui/GenerationCache.h b/libs/hwui/GenerationCache.h index c42a5d8..070e33f 100644 --- a/libs/hwui/GenerationCache.h +++ b/libs/hwui/GenerationCache.h @@ -61,6 +61,7 @@ public: bool contains(K key) const; V get(K key); + K getKeyAt(uint32_t index) const; void put(K key, V value); V remove(K key); V removeOldest(); @@ -122,6 +123,11 @@ bool GenerationCache<K, V>::contains(K key) const { } template<typename K, typename V> +K GenerationCache<K, V>::getKeyAt(uint32_t index) const { + return mCache.keyAt(index); +} + +template<typename K, typename V> V GenerationCache<K, V>::get(K key) { ssize_t index = mCache.indexOfKey(key); if (index >= 0) { diff --git a/libs/hwui/GradientCache.cpp b/libs/hwui/GradientCache.cpp index 58920bd..9957370 100644 --- a/libs/hwui/GradientCache.cpp +++ b/libs/hwui/GradientCache.cpp @@ -21,6 +21,8 @@ #include <SkCanvas.h> #include <SkGradientShader.h> +#include <utils/threads.h> + #include "GradientCache.h" #include "Properties.h" @@ -52,6 +54,7 @@ GradientCache::GradientCache(uint32_t maxByteSize): } GradientCache::~GradientCache() { + Mutex::Autolock _l(mLock); mCache.clear(); } @@ -60,14 +63,17 @@ GradientCache::~GradientCache() { /////////////////////////////////////////////////////////////////////////////// uint32_t GradientCache::getSize() { + Mutex::Autolock _l(mLock); return mSize; } uint32_t GradientCache::getMaxSize() { + Mutex::Autolock _l(mLock); return mMaxSize; } void GradientCache::setMaxSize(uint32_t maxSize) { + Mutex::Autolock _l(mLock); mMaxSize = maxSize; while (mSize > mMaxSize) { mCache.removeOldest(); @@ -79,6 +85,7 @@ void GradientCache::setMaxSize(uint32_t maxSize) { /////////////////////////////////////////////////////////////////////////////// void GradientCache::operator()(SkShader*& shader, Texture*& texture) { + // Already locked here if (shader) { const uint32_t size = texture->width * texture->height * 4; mSize -= size; @@ -95,14 +102,17 @@ void GradientCache::operator()(SkShader*& shader, Texture*& texture) { /////////////////////////////////////////////////////////////////////////////// Texture* GradientCache::get(SkShader* shader) { + Mutex::Autolock _l(mLock); return mCache.get(shader); } void GradientCache::remove(SkShader* shader) { + Mutex::Autolock _l(mLock); mCache.remove(shader); } void GradientCache::clear() { + Mutex::Autolock _l(mLock); mCache.clear(); } @@ -128,17 +138,21 @@ Texture* GradientCache::addLinearGradient(SkShader* shader, float* bounds, uint3 canvas.drawRectCoords(0.0f, 0.0f, bitmap.width(), 1.0f, p); + mLock.lock(); // Asume the cache is always big enough const uint32_t size = bitmap.rowBytes() * bitmap.height(); while (mSize + size > mMaxSize) { mCache.removeOldest(); } + mLock.unlock(); Texture* texture = new Texture; generateTexture(&bitmap, texture); + mLock.lock(); mSize += size; mCache.put(shader, texture); + mLock.unlock(); return texture; } diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h index 8795920..51a8c01 100644 --- a/libs/hwui/GradientCache.h +++ b/libs/hwui/GradientCache.h @@ -82,6 +82,12 @@ private: uint32_t mSize; uint32_t mMaxSize; + + /** + * Used to access mCache and mSize. All methods are accessed from a single + * thread except for remove(). + */ + mutable Mutex mLock; }; // class GradientCache }; // namespace uirenderer diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp index 158c0cc..e8afe37 100644 --- a/libs/hwui/PathCache.cpp +++ b/libs/hwui/PathCache.cpp @@ -21,6 +21,8 @@ #include <SkCanvas.h> #include <SkRect.h> +#include <utils/threads.h> + #include "PathCache.h" #include "Properties.h" @@ -51,6 +53,7 @@ PathCache::PathCache(uint32_t maxByteSize): } PathCache::~PathCache() { + Mutex::Autolock _l(mLock); mCache.clear(); } @@ -67,14 +70,17 @@ void PathCache::init() { /////////////////////////////////////////////////////////////////////////////// uint32_t PathCache::getSize() { + Mutex::Autolock _l(mLock); return mSize; } uint32_t PathCache::getMaxSize() { + Mutex::Autolock _l(mLock); return mMaxSize; } void PathCache::setMaxSize(uint32_t maxSize) { + Mutex::Autolock _l(mLock); mMaxSize = maxSize; while (mSize > mMaxSize) { mCache.removeOldest(); @@ -99,14 +105,30 @@ void PathCache::operator()(PathCacheEntry& path, PathTexture*& texture) { // Caching /////////////////////////////////////////////////////////////////////////////// +void PathCache::remove(SkPath* path) { + Mutex::Autolock _l(mLock); + // TODO: Linear search... + for (uint32_t i = 0; i < mCache.size(); i++) { + if (mCache.getKeyAt(i).path == path) { + mCache.removeAt(i); + return; + } + } +} + PathTexture* PathCache::get(SkPath* path, SkPaint* paint) { PathCacheEntry entry(path, paint); + + mLock.lock(); PathTexture* texture = mCache.get(entry); + mLock.unlock(); if (!texture) { texture = addTexture(entry, path, paint); } else if (path->getGenerationID() != texture->generation) { + mLock.lock(); mCache.remove(entry); + mLock.unlock(); texture = addTexture(entry, path, paint); } @@ -132,9 +154,11 @@ PathTexture* PathCache::addTexture(const PathCacheEntry& entry, const uint32_t size = width * 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(); } PathTexture* texture = new PathTexture; @@ -157,8 +181,10 @@ PathTexture* PathCache::addTexture(const PathCacheEntry& entry, generateTexture(bitmap, texture); if (size < mMaxSize) { + mLock.lock(); mSize += size; mCache.put(entry, texture); + mLock.unlock(); } else { texture->cleanup = true; } @@ -167,6 +193,7 @@ PathTexture* PathCache::addTexture(const PathCacheEntry& entry, } void PathCache::clear() { + Mutex::Autolock _l(mLock); mCache.clear(); } diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h index 522e5e0..bde0e7d 100644 --- a/libs/hwui/PathCache.h +++ b/libs/hwui/PathCache.h @@ -114,6 +114,10 @@ public: * Clears the cache. This causes all textures to be deleted. */ void clear(); + /** + * Removes an entry. + */ + void remove(SkPath* path); /** * Sets the maximum size of the cache in bytes. @@ -143,6 +147,12 @@ private: uint32_t mSize; uint32_t mMaxSize; GLuint mMaxTextureSize; + + /** + * Used to access mCache and mSize. All methods are accessed from a single + * thread except for remove(). + */ + mutable Mutex mLock; }; // class PathCache }; // namespace uirenderer diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp index e558870..927070a 100644 --- a/libs/hwui/TextureCache.cpp +++ b/libs/hwui/TextureCache.cpp @@ -102,9 +102,10 @@ void TextureCache::operator()(SkBitmap*& bitmap, Texture*& texture) { /////////////////////////////////////////////////////////////////////////////// Texture* TextureCache::get(SkBitmap* bitmap) { - Mutex::Autolock _l(mLock); - + mLock.lock(); Texture* texture = mCache.get(bitmap); + mLock.unlock(); + if (!texture) { if (bitmap->width() > mMaxTextureSize || bitmap->height() > mMaxTextureSize) { LOGW("Bitmap too large to be uploaded into a texture"); @@ -114,9 +115,11 @@ Texture* TextureCache::get(SkBitmap* bitmap) { 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; @@ -124,8 +127,10 @@ Texture* TextureCache::get(SkBitmap* bitmap) { generateTexture(bitmap, texture, false); if (size < mMaxSize) { + mLock.lock(); mSize += size; mCache.put(bitmap, texture); + mLock.unlock(); } else { texture->cleanup = true; } diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h index 847d69c..a63789a 100644 --- a/libs/hwui/TextureCache.h +++ b/libs/hwui/TextureCache.h @@ -87,6 +87,10 @@ private: uint32_t mMaxSize; GLint mMaxTextureSize; + /** + * Used to access mCache and mSize. All methods are accessed from a single + * thread except for remove(). + */ mutable Mutex mLock; }; // class TextureCache |
