GradientCache.h revision 8dcfd5e836341b4a803b04d104a930bb312182d3
1c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy/* 2c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Copyright (C) 2010 The Android Open Source Project 3c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * 4c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Licensed under the Apache License, Version 2.0 (the "License"); 5c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * you may not use this file except in compliance with the License. 6c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * You may obtain a copy of the License at 7c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * 8c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * http://www.apache.org/licenses/LICENSE-2.0 9c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * 10c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Unless required by applicable law or agreed to in writing, software 11c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * distributed under the License is distributed on an "AS IS" BASIS, 12c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * See the License for the specific language governing permissions and 14c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * limitations under the License. 15c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy */ 16c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 175b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#ifndef ANDROID_HWUI_GRADIENT_CACHE_H 185b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#define ANDROID_HWUI_GRADIENT_CACHE_H 19c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 208dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy#include <GLES2/gl2.h> 218dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy 22c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy#include <SkShader.h> 23c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 24029f64303b8fe506ef34c12777da86b830d3bf7aDerek Sollenberger#include <utils/Mutex.h> 25fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy#include <utils/Vector.h> 26fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy 27c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy#include "Texture.h" 286203f6c8147069976342be8f42add797a50f9557Romain Guy#include "utils/Compare.h" 2921b028a44f3e0bd9b0f0432b8b92c45f661d22a4Romain Guy#include "utils/GenerationCache.h" 30c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 31c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guynamespace android { 32c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guynamespace uirenderer { 33c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 346203f6c8147069976342be8f42add797a50f9557Romain Guystruct GradientCacheEntry { 356203f6c8147069976342be8f42add797a50f9557Romain Guy GradientCacheEntry() { 366203f6c8147069976342be8f42add797a50f9557Romain Guy count = 0; 376203f6c8147069976342be8f42add797a50f9557Romain Guy colors = NULL; 386203f6c8147069976342be8f42add797a50f9557Romain Guy positions = NULL; 396203f6c8147069976342be8f42add797a50f9557Romain Guy tileMode = SkShader::kClamp_TileMode; 406203f6c8147069976342be8f42add797a50f9557Romain Guy } 416203f6c8147069976342be8f42add797a50f9557Romain Guy 426203f6c8147069976342be8f42add797a50f9557Romain Guy GradientCacheEntry(uint32_t* colors, float* positions, int count, 436203f6c8147069976342be8f42add797a50f9557Romain Guy SkShader::TileMode tileMode) { 44e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy copy(colors, positions, count, tileMode); 456203f6c8147069976342be8f42add797a50f9557Romain Guy } 466203f6c8147069976342be8f42add797a50f9557Romain Guy 476203f6c8147069976342be8f42add797a50f9557Romain Guy GradientCacheEntry(const GradientCacheEntry& entry) { 48e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy copy(entry.colors, entry.positions, entry.count, entry.tileMode); 496203f6c8147069976342be8f42add797a50f9557Romain Guy } 506203f6c8147069976342be8f42add797a50f9557Romain Guy 516203f6c8147069976342be8f42add797a50f9557Romain Guy ~GradientCacheEntry() { 52e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy delete[] colors; 53e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy delete[] positions; 54e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy } 55e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy 56e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy GradientCacheEntry& operator=(const GradientCacheEntry& entry) { 57e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy if (this != &entry) { 58e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy delete[] colors; 59e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy delete[] positions; 60e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy 61e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy copy(entry.colors, entry.positions, entry.count, entry.tileMode); 62e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy } 63e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy 64e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy return *this; 656203f6c8147069976342be8f42add797a50f9557Romain Guy } 666203f6c8147069976342be8f42add797a50f9557Romain Guy 676203f6c8147069976342be8f42add797a50f9557Romain Guy bool operator<(const GradientCacheEntry& r) const { 686203f6c8147069976342be8f42add797a50f9557Romain Guy const GradientCacheEntry& rhs = (const GradientCacheEntry&) r; 696203f6c8147069976342be8f42add797a50f9557Romain Guy LTE_INT(count) { 706203f6c8147069976342be8f42add797a50f9557Romain Guy LTE_INT(tileMode) { 716203f6c8147069976342be8f42add797a50f9557Romain Guy int result = memcmp(colors, rhs.colors, count * sizeof(uint32_t)); 726203f6c8147069976342be8f42add797a50f9557Romain Guy if (result< 0) return true; 736203f6c8147069976342be8f42add797a50f9557Romain Guy else if (result == 0) { 746203f6c8147069976342be8f42add797a50f9557Romain Guy result = memcmp(positions, rhs.positions, count * sizeof(float)); 756203f6c8147069976342be8f42add797a50f9557Romain Guy if (result < 0) return true; 766203f6c8147069976342be8f42add797a50f9557Romain Guy } 776203f6c8147069976342be8f42add797a50f9557Romain Guy } 786203f6c8147069976342be8f42add797a50f9557Romain Guy } 796203f6c8147069976342be8f42add797a50f9557Romain Guy return false; 806203f6c8147069976342be8f42add797a50f9557Romain Guy } 816203f6c8147069976342be8f42add797a50f9557Romain Guy 826203f6c8147069976342be8f42add797a50f9557Romain Guy uint32_t* colors; 836203f6c8147069976342be8f42add797a50f9557Romain Guy float* positions; 846203f6c8147069976342be8f42add797a50f9557Romain Guy int count; 856203f6c8147069976342be8f42add797a50f9557Romain Guy SkShader::TileMode tileMode; 866203f6c8147069976342be8f42add797a50f9557Romain Guy 87e5df231434357424cea8d2b8d0cdf31253a98110Romain Guyprivate: 88e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy 89e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy void copy(uint32_t* colors, float* positions, int count, SkShader::TileMode tileMode) { 90e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy this->count = count; 91e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy this->colors = new uint32_t[count]; 92e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy this->positions = new float[count]; 93e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy this->tileMode = tileMode; 94e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy 95e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy memcpy(this->colors, colors, count * sizeof(uint32_t)); 96e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy memcpy(this->positions, positions, count * sizeof(float)); 97e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy } 98e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy 996203f6c8147069976342be8f42add797a50f9557Romain Guy}; // GradientCacheEntry 1006203f6c8147069976342be8f42add797a50f9557Romain Guy 101c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy/** 102c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * A simple LRU gradient cache. The cache has a maximum size expressed in bytes. 103c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Any texture added to the cache causing the cache to grow beyond the maximum 104c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * allowed size will also cause the oldest texture to be kicked out. 105c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy */ 1066203f6c8147069976342be8f42add797a50f9557Romain Guyclass GradientCache: public OnEntryRemoved<GradientCacheEntry, Texture*> { 107c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guypublic: 108fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy GradientCache(); 109c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy GradientCache(uint32_t maxByteSize); 110c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy ~GradientCache(); 111c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 112c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy /** 113c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Used as a callback when an entry is removed from the cache. 114c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Do not invoke directly. 115c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy */ 1166203f6c8147069976342be8f42add797a50f9557Romain Guy void operator()(GradientCacheEntry& shader, Texture*& texture); 117c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 118c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy /** 119c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Returns the texture associated with the specified shader. 120c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy */ 1216203f6c8147069976342be8f42add797a50f9557Romain Guy Texture* get(uint32_t* colors, float* positions, 1226203f6c8147069976342be8f42add797a50f9557Romain Guy int count, SkShader::TileMode tileMode = SkShader::kClamp_TileMode); 123fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy /** 124c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Clears the cache. This causes all textures to be deleted. 125c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy */ 126c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy void clear(); 127c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 128c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy /** 129c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Sets the maximum size of the cache in bytes. 130c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy */ 131c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy void setMaxSize(uint32_t maxSize); 132c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy /** 133c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Returns the maximum size of the cache in bytes. 134c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy */ 135c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy uint32_t getMaxSize(); 136c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy /** 137c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Returns the current size of the cache in bytes. 138c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy */ 139c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy uint32_t getSize(); 140c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 141c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guyprivate: 1426203f6c8147069976342be8f42add797a50f9557Romain Guy /** 1436203f6c8147069976342be8f42add797a50f9557Romain Guy * Adds a new linear gradient to the cache. The generated texture is 1446203f6c8147069976342be8f42add797a50f9557Romain Guy * returned. 1456203f6c8147069976342be8f42add797a50f9557Romain Guy */ 1466203f6c8147069976342be8f42add797a50f9557Romain Guy Texture* addLinearGradient(GradientCacheEntry& gradient, 1476203f6c8147069976342be8f42add797a50f9557Romain Guy uint32_t* colors, float* positions, int count, 1486203f6c8147069976342be8f42add797a50f9557Romain Guy SkShader::TileMode tileMode = SkShader::kClamp_TileMode); 1496203f6c8147069976342be8f42add797a50f9557Romain Guy 150c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy void generateTexture(SkBitmap* bitmap, Texture* texture); 151c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 1526203f6c8147069976342be8f42add797a50f9557Romain Guy GenerationCache<GradientCacheEntry, Texture*> mCache; 153c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 154c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy uint32_t mSize; 155c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy uint32_t mMaxSize; 156a2341a9f6addcd79723965ec5b1a1c5ae0f8bd65Romain Guy 1578dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy GLint mMaxTextureSize; 1588dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy 159fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy Vector<SkShader*> mGarbage; 160a2341a9f6addcd79723965ec5b1a1c5ae0f8bd65Romain Guy mutable Mutex mLock; 161c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy}; // class GradientCache 162c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 163c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy}; // namespace uirenderer 164c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy}; // namespace android 165c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 1665b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#endif // ANDROID_HWUI_GRADIENT_CACHE_H 167