1 /* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ANDROID_HWUI_GRADIENT_CACHE_H 18 #define ANDROID_HWUI_GRADIENT_CACHE_H 19 20 #include <SkShader.h> 21 22 #include <utils/Vector.h> 23 24 #include "Texture.h" 25 #include "utils/Compare.h" 26 #include "utils/GenerationCache.h" 27 28 namespace android { 29 namespace uirenderer { 30 31 struct GradientCacheEntry { GradientCacheEntryGradientCacheEntry32 GradientCacheEntry() { 33 count = 0; 34 colors = NULL; 35 positions = NULL; 36 tileMode = SkShader::kClamp_TileMode; 37 } 38 GradientCacheEntryGradientCacheEntry39 GradientCacheEntry(uint32_t* colors, float* positions, int count, 40 SkShader::TileMode tileMode) { 41 copy(colors, positions, count, tileMode); 42 } 43 GradientCacheEntryGradientCacheEntry44 GradientCacheEntry(const GradientCacheEntry& entry) { 45 copy(entry.colors, entry.positions, entry.count, entry.tileMode); 46 } 47 ~GradientCacheEntryGradientCacheEntry48 ~GradientCacheEntry() { 49 delete[] colors; 50 delete[] positions; 51 } 52 53 GradientCacheEntry& operator=(const GradientCacheEntry& entry) { 54 if (this != &entry) { 55 delete[] colors; 56 delete[] positions; 57 58 copy(entry.colors, entry.positions, entry.count, entry.tileMode); 59 } 60 61 return *this; 62 } 63 64 bool operator<(const GradientCacheEntry& r) const { 65 const GradientCacheEntry& rhs = (const GradientCacheEntry&) r; LTE_INTGradientCacheEntry66 LTE_INT(count) { 67 LTE_INT(tileMode) { 68 int result = memcmp(colors, rhs.colors, count * sizeof(uint32_t)); 69 if (result< 0) return true; 70 else if (result == 0) { 71 result = memcmp(positions, rhs.positions, count * sizeof(float)); 72 if (result < 0) return true; 73 } 74 } 75 } 76 return false; 77 } 78 79 uint32_t* colors; 80 float* positions; 81 int count; 82 SkShader::TileMode tileMode; 83 84 private: 85 copyGradientCacheEntry86 void copy(uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode) { 87 this->count = count; 88 this->colors = new uint32_t[count]; 89 this->positions = new float[count]; 90 this->tileMode = tileMode; 91 92 memcpy(this->colors, colors, count * sizeof(uint32_t)); 93 memcpy(this->positions, positions, count * sizeof(float)); 94 } 95 96 }; // GradientCacheEntry 97 98 /** 99 * A simple LRU gradient cache. The cache has a maximum size expressed in bytes. 100 * Any texture added to the cache causing the cache to grow beyond the maximum 101 * allowed size will also cause the oldest texture to be kicked out. 102 */ 103 class GradientCache: public OnEntryRemoved<GradientCacheEntry, Texture*> { 104 public: 105 GradientCache(); 106 GradientCache(uint32_t maxByteSize); 107 ~GradientCache(); 108 109 /** 110 * Used as a callback when an entry is removed from the cache. 111 * Do not invoke directly. 112 */ 113 void operator()(GradientCacheEntry& shader, Texture*& texture); 114 115 /** 116 * Returns the texture associated with the specified shader. 117 */ 118 Texture* get(uint32_t* colors, float* positions, 119 int count, SkShader::TileMode tileMode = SkShader::kClamp_TileMode); 120 /** 121 * Clears the cache. This causes all textures to be deleted. 122 */ 123 void clear(); 124 125 /** 126 * Sets the maximum size of the cache in bytes. 127 */ 128 void setMaxSize(uint32_t maxSize); 129 /** 130 * Returns the maximum size of the cache in bytes. 131 */ 132 uint32_t getMaxSize(); 133 /** 134 * Returns the current size of the cache in bytes. 135 */ 136 uint32_t getSize(); 137 138 private: 139 /** 140 * Adds a new linear gradient to the cache. The generated texture is 141 * returned. 142 */ 143 Texture* addLinearGradient(GradientCacheEntry& gradient, 144 uint32_t* colors, float* positions, int count, 145 SkShader::TileMode tileMode = SkShader::kClamp_TileMode); 146 147 void generateTexture(SkBitmap* bitmap, Texture* texture); 148 149 GenerationCache<GradientCacheEntry, Texture*> mCache; 150 151 uint32_t mSize; 152 uint32_t mMaxSize; 153 154 Vector<SkShader*> mGarbage; 155 mutable Mutex mLock; 156 }; // class GradientCache 157 158 }; // namespace uirenderer 159 }; // namespace android 160 161 #endif // ANDROID_HWUI_GRADIENT_CACHE_H 162