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