Reduce the amount of data cached by the gradients cache.
Change-Id: I8546f5a5ecf38031c9a40bdcc434d4c7f22da63d
diff --git a/libs/hwui/GradientCache.h b/libs/hwui/GradientCache.h
index 30da462..086921c 100644
--- a/libs/hwui/GradientCache.h
+++ b/libs/hwui/GradientCache.h
@@ -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);
@@ -42,32 +99,13 @@
* 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.
*/
@@ -87,9 +125,17 @@
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;