Loading libs/hwui/Caches.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -142,7 +142,6 @@ void Caches::dumpMemoryUsage(String8 &log) { void Caches::clearGarbage() { textureCache.clearGarbage(); gradientCache.clearGarbage(); pathCache.clearGarbage(); Mutex::Autolock _l(mGarbageLock); Loading libs/hwui/GradientCache.cpp +15 −25 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// GradientCache::GradientCache(): mCache(GenerationCache<SkShader*, Texture*>::kUnlimitedCapacity), mCache(GenerationCache<GradientCacheEntry, Texture*>::kUnlimitedCapacity), mSize(0), mMaxSize(MB(DEFAULT_GRADIENT_CACHE_SIZE)) { char property[PROPERTY_VALUE_MAX]; if (property_get(PROPERTY_GRADIENT_CACHE_SIZE, property, NULL) > 0) { Loading @@ -49,7 +49,7 @@ GradientCache::GradientCache(): } GradientCache::GradientCache(uint32_t maxByteSize): mCache(GenerationCache<SkShader*, Texture*>::kUnlimitedCapacity), mCache(GenerationCache<GradientCacheEntry, Texture*>::kUnlimitedCapacity), mSize(0), mMaxSize(maxByteSize) { mCache.setOnEntryRemovedListener(this); } Loading Loading @@ -81,9 +81,8 @@ void GradientCache::setMaxSize(uint32_t maxSize) { // Callbacks /////////////////////////////////////////////////////////////////////////////// void GradientCache::operator()(SkShader*& shader, Texture*& texture) { // Already locked here if (shader) { void GradientCache::operator()(GradientCacheEntry& shader, Texture*& texture) { if (texture) { const uint32_t size = texture->width * texture->height * 4; mSize -= size; } Loading @@ -98,34 +97,25 @@ void GradientCache::operator()(SkShader*& shader, Texture*& texture) { // Caching /////////////////////////////////////////////////////////////////////////////// Texture* GradientCache::get(SkShader* shader) { return mCache.get(shader); } Texture* GradientCache::get(uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode) { void GradientCache::remove(SkShader* shader) { mCache.remove(shader); } GradientCacheEntry gradient(colors, positions, count, tileMode); Texture* texture = mCache.get(gradient); void GradientCache::removeDeferred(SkShader* shader) { Mutex::Autolock _l(mLock); mGarbage.push(shader); if (!texture) { texture = addLinearGradient(gradient, colors, positions, count, tileMode); } void GradientCache::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(); return texture; } void GradientCache::clear() { mCache.clear(); } Texture* GradientCache::addLinearGradient(SkShader* shader, uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode) { Texture* GradientCache::addLinearGradient(GradientCacheEntry& gradient, uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode) { SkBitmap bitmap; bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1024, 1); bitmap.allocPixels(); Loading Loading @@ -156,7 +146,7 @@ Texture* GradientCache::addLinearGradient(SkShader* shader, uint32_t* colors, generateTexture(&bitmap, texture); mSize += size; mCache.put(shader, texture); mCache.put(gradient, texture); return texture; } Loading libs/hwui/GradientCache.h +70 −24 Original line number Diff line number Diff line Loading @@ -22,17 +22,74 @@ #include <utils/Vector.h> #include "Texture.h" #include "utils/Compare.h" #include "utils/GenerationCache.h" namespace android { namespace uirenderer { struct GradientCacheEntry { GradientCacheEntry() { count = 0; colors = NULL; positions = NULL; tileMode = SkShader::kClamp_TileMode; } GradientCacheEntry(uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode) { this->count = count; this->colors = new uint32_t[count]; this->positions = new float[count]; this->tileMode = tileMode; memcpy(this->colors, colors, count * sizeof(uint32_t)); memcpy(this->positions, positions, count * sizeof(float)); } GradientCacheEntry(const GradientCacheEntry& entry) { this->count = entry.count; this->colors = new uint32_t[count]; this->positions = new float[count]; this->tileMode = entry.tileMode; memcpy(this->colors, entry.colors, count * sizeof(uint32_t)); memcpy(this->positions, entry.positions, count * sizeof(float)); } ~GradientCacheEntry() { delete[] colors; delete[] positions; } bool operator<(const GradientCacheEntry& r) const { const GradientCacheEntry& rhs = (const GradientCacheEntry&) r; LTE_INT(count) { LTE_INT(tileMode) { int result = memcmp(colors, rhs.colors, count * sizeof(uint32_t)); if (result< 0) return true; else if (result == 0) { result = memcmp(positions, rhs.positions, count * sizeof(float)); if (result < 0) return true; } } } return false; } uint32_t* colors; float* positions; int count; SkShader::TileMode tileMode; }; // GradientCacheEntry /** * A simple LRU gradient cache. The cache has a maximum size expressed in bytes. * Any texture added to the cache causing the cache to grow beyond the maximum * allowed size will also cause the oldest texture to be kicked out. */ class GradientCache: public OnEntryRemoved<SkShader*, Texture*> { class GradientCache: public OnEntryRemoved<GradientCacheEntry, Texture*> { public: GradientCache(); GradientCache(uint32_t maxByteSize); Loading @@ -42,32 +99,13 @@ public: * Used as a callback when an entry is removed from the cache. * Do not invoke directly. */ void operator()(SkShader*& shader, Texture*& texture); void operator()(GradientCacheEntry& shader, Texture*& texture); /** * Adds a new linear gradient to the cache. The generated texture is * returned. */ Texture* addLinearGradient(SkShader* shader, uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode = SkShader::kClamp_TileMode); /** * Returns the texture associated with the specified shader. */ Texture* get(SkShader* shader); /** * Removes the texture associated with the specified shader. * Upon remove the texture is freed. */ void remove(SkShader* shader); /** * Removes the texture associated with the specified shader. This is meant * to be called from threads that are not the EGL context thread. */ void removeDeferred(SkShader* shader); /** * Process deferred removals. */ void clearGarbage(); Texture* get(uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode = SkShader::kClamp_TileMode); /** * Clears the cache. This causes all textures to be deleted. */ Loading @@ -87,9 +125,17 @@ public: uint32_t getSize(); private: /** * Adds a new linear gradient to the cache. The generated texture is * returned. */ Texture* addLinearGradient(GradientCacheEntry& gradient, uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode = SkShader::kClamp_TileMode); void generateTexture(SkBitmap* bitmap, Texture* texture); GenerationCache<SkShader*, Texture*> mCache; GenerationCache<GradientCacheEntry, Texture*> mCache; uint32_t mSize; uint32_t mMaxSize; Loading libs/hwui/ResourceCache.cpp +0 −6 Original line number Diff line number Diff line Loading @@ -166,9 +166,6 @@ void ResourceCache::destructor(SkiaShader* resource) { ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; if (ref == NULL) { // If we're not tracking this resource, just delete it if (Caches::hasInstance()) { Caches::getInstance().gradientCache.removeDeferred(resource->getSkShader()); } delete resource; return; } Loading Loading @@ -220,9 +217,6 @@ void ResourceCache::deleteResourceReference(void* resource, ResourceReference* r break; case kShader: { SkiaShader* shader = (SkiaShader*) resource; if (Caches::hasInstance()) { Caches::getInstance().gradientCache.removeDeferred(shader->getSkShader()); } delete shader; } break; Loading libs/hwui/SkiaShader.cpp +2 −8 Original line number Diff line number Diff line Loading @@ -225,10 +225,7 @@ void SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelV GLuint textureSlot = (*textureUnit)++; glActiveTexture(gTextureUnitsMap[textureSlot]); Texture* texture = mGradientCache->get(mKey); if (!texture) { texture = mGradientCache->addLinearGradient(mKey, mColors, mPositions, mCount, mTileX); } Texture* texture = mGradientCache->get(mColors, mPositions, mCount, mTileX); mat4 screenSpace; computeScreenSpaceMatrix(screenSpace, modelView); Loading Loading @@ -340,10 +337,7 @@ void SkiaSweepGradientShader::setupProgram(Program* program, const mat4& modelVi GLuint textureSlot = (*textureUnit)++; glActiveTexture(gTextureUnitsMap[textureSlot]); Texture* texture = mGradientCache->get(mKey); if (!texture) { texture = mGradientCache->addLinearGradient(mKey, mColors, mPositions, mCount); } Texture* texture = mGradientCache->get(mColors, mPositions, mCount); mat4 screenSpace; computeScreenSpaceMatrix(screenSpace, modelView); Loading Loading
libs/hwui/Caches.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -142,7 +142,6 @@ void Caches::dumpMemoryUsage(String8 &log) { void Caches::clearGarbage() { textureCache.clearGarbage(); gradientCache.clearGarbage(); pathCache.clearGarbage(); Mutex::Autolock _l(mGarbageLock); Loading
libs/hwui/GradientCache.cpp +15 −25 Original line number Diff line number Diff line Loading @@ -35,7 +35,7 @@ namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// GradientCache::GradientCache(): mCache(GenerationCache<SkShader*, Texture*>::kUnlimitedCapacity), mCache(GenerationCache<GradientCacheEntry, Texture*>::kUnlimitedCapacity), mSize(0), mMaxSize(MB(DEFAULT_GRADIENT_CACHE_SIZE)) { char property[PROPERTY_VALUE_MAX]; if (property_get(PROPERTY_GRADIENT_CACHE_SIZE, property, NULL) > 0) { Loading @@ -49,7 +49,7 @@ GradientCache::GradientCache(): } GradientCache::GradientCache(uint32_t maxByteSize): mCache(GenerationCache<SkShader*, Texture*>::kUnlimitedCapacity), mCache(GenerationCache<GradientCacheEntry, Texture*>::kUnlimitedCapacity), mSize(0), mMaxSize(maxByteSize) { mCache.setOnEntryRemovedListener(this); } Loading Loading @@ -81,9 +81,8 @@ void GradientCache::setMaxSize(uint32_t maxSize) { // Callbacks /////////////////////////////////////////////////////////////////////////////// void GradientCache::operator()(SkShader*& shader, Texture*& texture) { // Already locked here if (shader) { void GradientCache::operator()(GradientCacheEntry& shader, Texture*& texture) { if (texture) { const uint32_t size = texture->width * texture->height * 4; mSize -= size; } Loading @@ -98,34 +97,25 @@ void GradientCache::operator()(SkShader*& shader, Texture*& texture) { // Caching /////////////////////////////////////////////////////////////////////////////// Texture* GradientCache::get(SkShader* shader) { return mCache.get(shader); } Texture* GradientCache::get(uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode) { void GradientCache::remove(SkShader* shader) { mCache.remove(shader); } GradientCacheEntry gradient(colors, positions, count, tileMode); Texture* texture = mCache.get(gradient); void GradientCache::removeDeferred(SkShader* shader) { Mutex::Autolock _l(mLock); mGarbage.push(shader); if (!texture) { texture = addLinearGradient(gradient, colors, positions, count, tileMode); } void GradientCache::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(); return texture; } void GradientCache::clear() { mCache.clear(); } Texture* GradientCache::addLinearGradient(SkShader* shader, uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode) { Texture* GradientCache::addLinearGradient(GradientCacheEntry& gradient, uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode) { SkBitmap bitmap; bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1024, 1); bitmap.allocPixels(); Loading Loading @@ -156,7 +146,7 @@ Texture* GradientCache::addLinearGradient(SkShader* shader, uint32_t* colors, generateTexture(&bitmap, texture); mSize += size; mCache.put(shader, texture); mCache.put(gradient, texture); return texture; } Loading
libs/hwui/GradientCache.h +70 −24 Original line number Diff line number Diff line Loading @@ -22,17 +22,74 @@ #include <utils/Vector.h> #include "Texture.h" #include "utils/Compare.h" #include "utils/GenerationCache.h" namespace android { namespace uirenderer { struct GradientCacheEntry { GradientCacheEntry() { count = 0; colors = NULL; positions = NULL; tileMode = SkShader::kClamp_TileMode; } GradientCacheEntry(uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode) { this->count = count; this->colors = new uint32_t[count]; this->positions = new float[count]; this->tileMode = tileMode; memcpy(this->colors, colors, count * sizeof(uint32_t)); memcpy(this->positions, positions, count * sizeof(float)); } GradientCacheEntry(const GradientCacheEntry& entry) { this->count = entry.count; this->colors = new uint32_t[count]; this->positions = new float[count]; this->tileMode = entry.tileMode; memcpy(this->colors, entry.colors, count * sizeof(uint32_t)); memcpy(this->positions, entry.positions, count * sizeof(float)); } ~GradientCacheEntry() { delete[] colors; delete[] positions; } bool operator<(const GradientCacheEntry& r) const { const GradientCacheEntry& rhs = (const GradientCacheEntry&) r; LTE_INT(count) { LTE_INT(tileMode) { int result = memcmp(colors, rhs.colors, count * sizeof(uint32_t)); if (result< 0) return true; else if (result == 0) { result = memcmp(positions, rhs.positions, count * sizeof(float)); if (result < 0) return true; } } } return false; } uint32_t* colors; float* positions; int count; SkShader::TileMode tileMode; }; // GradientCacheEntry /** * A simple LRU gradient cache. The cache has a maximum size expressed in bytes. * Any texture added to the cache causing the cache to grow beyond the maximum * allowed size will also cause the oldest texture to be kicked out. */ class GradientCache: public OnEntryRemoved<SkShader*, Texture*> { class GradientCache: public OnEntryRemoved<GradientCacheEntry, Texture*> { public: GradientCache(); GradientCache(uint32_t maxByteSize); Loading @@ -42,32 +99,13 @@ public: * Used as a callback when an entry is removed from the cache. * Do not invoke directly. */ void operator()(SkShader*& shader, Texture*& texture); void operator()(GradientCacheEntry& shader, Texture*& texture); /** * Adds a new linear gradient to the cache. The generated texture is * returned. */ Texture* addLinearGradient(SkShader* shader, uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode = SkShader::kClamp_TileMode); /** * Returns the texture associated with the specified shader. */ Texture* get(SkShader* shader); /** * Removes the texture associated with the specified shader. * Upon remove the texture is freed. */ void remove(SkShader* shader); /** * Removes the texture associated with the specified shader. This is meant * to be called from threads that are not the EGL context thread. */ void removeDeferred(SkShader* shader); /** * Process deferred removals. */ void clearGarbage(); Texture* get(uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode = SkShader::kClamp_TileMode); /** * Clears the cache. This causes all textures to be deleted. */ Loading @@ -87,9 +125,17 @@ public: uint32_t getSize(); private: /** * Adds a new linear gradient to the cache. The generated texture is * returned. */ Texture* addLinearGradient(GradientCacheEntry& gradient, uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode = SkShader::kClamp_TileMode); void generateTexture(SkBitmap* bitmap, Texture* texture); GenerationCache<SkShader*, Texture*> mCache; GenerationCache<GradientCacheEntry, Texture*> mCache; uint32_t mSize; uint32_t mMaxSize; Loading
libs/hwui/ResourceCache.cpp +0 −6 Original line number Diff line number Diff line Loading @@ -166,9 +166,6 @@ void ResourceCache::destructor(SkiaShader* resource) { ResourceReference* ref = mCache->indexOfKey(resource) >= 0 ? mCache->valueFor(resource) : NULL; if (ref == NULL) { // If we're not tracking this resource, just delete it if (Caches::hasInstance()) { Caches::getInstance().gradientCache.removeDeferred(resource->getSkShader()); } delete resource; return; } Loading Loading @@ -220,9 +217,6 @@ void ResourceCache::deleteResourceReference(void* resource, ResourceReference* r break; case kShader: { SkiaShader* shader = (SkiaShader*) resource; if (Caches::hasInstance()) { Caches::getInstance().gradientCache.removeDeferred(shader->getSkShader()); } delete shader; } break; Loading
libs/hwui/SkiaShader.cpp +2 −8 Original line number Diff line number Diff line Loading @@ -225,10 +225,7 @@ void SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelV GLuint textureSlot = (*textureUnit)++; glActiveTexture(gTextureUnitsMap[textureSlot]); Texture* texture = mGradientCache->get(mKey); if (!texture) { texture = mGradientCache->addLinearGradient(mKey, mColors, mPositions, mCount, mTileX); } Texture* texture = mGradientCache->get(mColors, mPositions, mCount, mTileX); mat4 screenSpace; computeScreenSpaceMatrix(screenSpace, modelView); Loading Loading @@ -340,10 +337,7 @@ void SkiaSweepGradientShader::setupProgram(Program* program, const mat4& modelVi GLuint textureSlot = (*textureUnit)++; glActiveTexture(gTextureUnitsMap[textureSlot]); Texture* texture = mGradientCache->get(mKey); if (!texture) { texture = mGradientCache->addLinearGradient(mKey, mColors, mPositions, mCount); } Texture* texture = mGradientCache->get(mColors, mPositions, mCount); mat4 screenSpace; computeScreenSpaceMatrix(screenSpace, modelView); Loading