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 <GLES2/gl2.h> 21 22 #include <SkShader.h> 23 24 #include <utils/Mutex.h> 25 #include <utils/Vector.h> 26 27 #include "Texture.h" 28 #include "utils/Compare.h" 29 #include "utils/GenerationCache.h" 30 31 namespace android { 32 namespace uirenderer { 33 34 struct GradientCacheEntry { GradientCacheEntryGradientCacheEntry35 GradientCacheEntry() { 36 count = 0; 37 colors = NULL; 38 positions = NULL; 39 } 40 GradientCacheEntryGradientCacheEntry41 GradientCacheEntry(uint32_t* colors, float* positions, int count) { 42 copy(colors, positions, count); 43 } 44 GradientCacheEntryGradientCacheEntry45 GradientCacheEntry(const GradientCacheEntry& entry) { 46 copy(entry.colors, entry.positions, entry.count); 47 } 48 ~GradientCacheEntryGradientCacheEntry49 ~GradientCacheEntry() { 50 delete[] colors; 51 delete[] positions; 52 } 53 54 GradientCacheEntry& operator=(const GradientCacheEntry& entry) { 55 if (this != &entry) { 56 delete[] colors; 57 delete[] positions; 58 59 copy(entry.colors, entry.positions, entry.count); 60 } 61 62 return *this; 63 } 64 65 bool operator<(const GradientCacheEntry& r) const { 66 const GradientCacheEntry& rhs = (const GradientCacheEntry&) r; LTE_INTGradientCacheEntry67 LTE_INT(count) { 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 return false; 76 } 77 78 uint32_t* colors; 79 float* positions; 80 int count; 81 SkShader::TileMode tileMode; 82 83 private: 84 copyGradientCacheEntry85 void copy(uint32_t* colors, float* positions, int count) { 86 this->count = count; 87 this->colors = new uint32_t[count]; 88 this->positions = new float[count]; 89 90 memcpy(this->colors, colors, count * sizeof(uint32_t)); 91 memcpy(this->positions, positions, count * sizeof(float)); 92 } 93 94 }; // GradientCacheEntry 95 96 /** 97 * A simple LRU gradient cache. The cache has a maximum size expressed in bytes. 98 * Any texture added to the cache causing the cache to grow beyond the maximum 99 * allowed size will also cause the oldest texture to be kicked out. 100 */ 101 class GradientCache: public OnEntryRemoved<GradientCacheEntry, Texture*> { 102 public: 103 GradientCache(); 104 GradientCache(uint32_t maxByteSize); 105 ~GradientCache(); 106 107 /** 108 * Used as a callback when an entry is removed from the cache. 109 * Do not invoke directly. 110 */ 111 void operator()(GradientCacheEntry& shader, Texture*& texture); 112 113 /** 114 * Returns the texture associated with the specified shader. 115 */ 116 Texture* get(uint32_t* colors, float* positions, int count); 117 118 /** 119 * Clears the cache. This causes all textures to be deleted. 120 */ 121 void clear(); 122 123 /** 124 * Sets the maximum size of the cache in bytes. 125 */ 126 void setMaxSize(uint32_t maxSize); 127 /** 128 * Returns the maximum size of the cache in bytes. 129 */ 130 uint32_t getMaxSize(); 131 /** 132 * Returns the current size of the cache in bytes. 133 */ 134 uint32_t getSize(); 135 136 private: 137 /** 138 * Adds a new linear gradient to the cache. The generated texture is 139 * returned. 140 */ 141 Texture* addLinearGradient(GradientCacheEntry& gradient, 142 uint32_t* colors, float* positions, int count); 143 144 void generateTexture(uint32_t* colors, float* positions, int count, Texture* texture); 145 146 struct GradientInfo { 147 uint32_t width; 148 bool hasAlpha; 149 }; 150 151 void getGradientInfo(const uint32_t* colors, const int count, GradientInfo& info); 152 153 GenerationCache<GradientCacheEntry, Texture*> mCache; 154 155 uint32_t mSize; 156 uint32_t mMaxSize; 157 158 GLint mMaxTextureSize; 159 160 Vector<SkShader*> mGarbage; 161 mutable Mutex mLock; 162 }; // class GradientCache 163 164 }; // namespace uirenderer 165 }; // namespace android 166 167 #endif // ANDROID_HWUI_GRADIENT_CACHE_H 168