GradientCache.h revision b48800428906ae455c2b63acacd44e390e1fee49
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 20b48800428906ae455c2b63acacd44e390e1fee49Romain Guy#include <GLES3/gl3.h> 218dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy 22c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy#include <SkShader.h> 23c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 24059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy#include <utils/LruCache.h> 25029f64303b8fe506ef34c12777da86b830d3bf7aDerek Sollenberger#include <utils/Mutex.h> 26fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy#include <utils/Vector.h> 27fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy 28c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy#include "Texture.h" 29c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 30c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guynamespace android { 31c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guynamespace uirenderer { 32c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 336203f6c8147069976342be8f42add797a50f9557Romain Guystruct GradientCacheEntry { 346203f6c8147069976342be8f42add797a50f9557Romain Guy GradientCacheEntry() { 356203f6c8147069976342be8f42add797a50f9557Romain Guy count = 0; 366203f6c8147069976342be8f42add797a50f9557Romain Guy colors = NULL; 376203f6c8147069976342be8f42add797a50f9557Romain Guy positions = NULL; 386203f6c8147069976342be8f42add797a50f9557Romain Guy } 396203f6c8147069976342be8f42add797a50f9557Romain Guy 40059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy GradientCacheEntry(uint32_t* colors, float* positions, uint32_t count) { 4142e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy copy(colors, positions, count); 426203f6c8147069976342be8f42add797a50f9557Romain Guy } 436203f6c8147069976342be8f42add797a50f9557Romain Guy 446203f6c8147069976342be8f42add797a50f9557Romain Guy GradientCacheEntry(const GradientCacheEntry& entry) { 4542e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy copy(entry.colors, entry.positions, entry.count); 466203f6c8147069976342be8f42add797a50f9557Romain Guy } 476203f6c8147069976342be8f42add797a50f9557Romain Guy 486203f6c8147069976342be8f42add797a50f9557Romain Guy ~GradientCacheEntry() { 49e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy delete[] colors; 50e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy delete[] positions; 51e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy } 52e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy 53e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy GradientCacheEntry& operator=(const GradientCacheEntry& entry) { 54e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy if (this != &entry) { 55e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy delete[] colors; 56e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy delete[] positions; 57e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy 5842e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy copy(entry.colors, entry.positions, entry.count); 59e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy } 60e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy 61e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy return *this; 626203f6c8147069976342be8f42add797a50f9557Romain Guy } 636203f6c8147069976342be8f42add797a50f9557Romain Guy 64059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy hash_t hash() const; 65059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy 66059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy static int compare(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs); 67059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy 68059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy bool operator==(const GradientCacheEntry& other) const { 69059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy return compare(*this, other) == 0; 70059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy } 71059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy 72059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy bool operator!=(const GradientCacheEntry& other) const { 73059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy return compare(*this, other) != 0; 746203f6c8147069976342be8f42add797a50f9557Romain Guy } 756203f6c8147069976342be8f42add797a50f9557Romain Guy 766203f6c8147069976342be8f42add797a50f9557Romain Guy uint32_t* colors; 776203f6c8147069976342be8f42add797a50f9557Romain Guy float* positions; 78059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy uint32_t count; 796203f6c8147069976342be8f42add797a50f9557Romain Guy 80e5df231434357424cea8d2b8d0cdf31253a98110Romain Guyprivate: 81059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy void copy(uint32_t* colors, float* positions, uint32_t count) { 82e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy this->count = count; 83e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy this->colors = new uint32_t[count]; 84e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy this->positions = new float[count]; 85e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy 86e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy memcpy(this->colors, colors, count * sizeof(uint32_t)); 87e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy memcpy(this->positions, positions, count * sizeof(float)); 88e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy } 89e5df231434357424cea8d2b8d0cdf31253a98110Romain Guy 906203f6c8147069976342be8f42add797a50f9557Romain Guy}; // GradientCacheEntry 916203f6c8147069976342be8f42add797a50f9557Romain Guy 92059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy// Caching support 93059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy 94059e12ccd20f5c249724a8362d6bac325334ea76Romain Guyinline int strictly_order_type(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs) { 95059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy return GradientCacheEntry::compare(lhs, rhs) < 0; 96059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy} 97059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy 98059e12ccd20f5c249724a8362d6bac325334ea76Romain Guyinline int compare_type(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs) { 99059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy return GradientCacheEntry::compare(lhs, rhs); 100059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy} 101059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy 102059e12ccd20f5c249724a8362d6bac325334ea76Romain Guyinline hash_t hash_type(const GradientCacheEntry& entry) { 103059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy return entry.hash(); 104059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy} 105059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy 106c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy/** 107c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * A simple LRU gradient cache. The cache has a maximum size expressed in bytes. 108c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Any texture added to the cache causing the cache to grow beyond the maximum 109c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * allowed size will also cause the oldest texture to be kicked out. 110c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy */ 1116203f6c8147069976342be8f42add797a50f9557Romain Guyclass GradientCache: public OnEntryRemoved<GradientCacheEntry, Texture*> { 112c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guypublic: 113fb8b763f762ae21923c58d64caa729b012f40e05Romain Guy GradientCache(); 114c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy GradientCache(uint32_t maxByteSize); 115c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy ~GradientCache(); 116c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 117c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy /** 118c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Used as a callback when an entry is removed from the cache. 119c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Do not invoke directly. 120c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy */ 1216203f6c8147069976342be8f42add797a50f9557Romain Guy void operator()(GradientCacheEntry& shader, Texture*& texture); 122c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 123c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy /** 124c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Returns the texture associated with the specified shader. 125c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy */ 12642e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy Texture* get(uint32_t* colors, float* positions, int count); 12742e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 128fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy /** 129c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Clears the cache. This causes all textures to be deleted. 130c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy */ 131c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy void clear(); 132c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 133c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy /** 134c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Sets the maximum size of the cache in bytes. 135c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy */ 136c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy void setMaxSize(uint32_t maxSize); 137c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy /** 138c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Returns the maximum size of the cache in bytes. 139c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy */ 140c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy uint32_t getMaxSize(); 141c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy /** 142c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy * Returns the current size of the cache in bytes. 143c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy */ 144c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy uint32_t getSize(); 145c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 146c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guyprivate: 1476203f6c8147069976342be8f42add797a50f9557Romain Guy /** 1486203f6c8147069976342be8f42add797a50f9557Romain Guy * Adds a new linear gradient to the cache. The generated texture is 1496203f6c8147069976342be8f42add797a50f9557Romain Guy * returned. 1506203f6c8147069976342be8f42add797a50f9557Romain Guy */ 1516203f6c8147069976342be8f42add797a50f9557Romain Guy Texture* addLinearGradient(GradientCacheEntry& gradient, 15242e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy uint32_t* colors, float* positions, int count); 15342e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 15442e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy void generateTexture(uint32_t* colors, float* positions, int count, Texture* texture); 15542e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy 15642e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy struct GradientInfo { 15742e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy uint32_t width; 15842e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy bool hasAlpha; 15942e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy }; 1606203f6c8147069976342be8f42add797a50f9557Romain Guy 16142e1e0d482d774cf18a55773e434f02edb9e4462Romain Guy void getGradientInfo(const uint32_t* colors, const int count, GradientInfo& info); 162c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 163b48800428906ae455c2b63acacd44e390e1fee49Romain Guy size_t bytesPerPixel() const; 164b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 165b48800428906ae455c2b63acacd44e390e1fee49Romain Guy struct GradientColor { 166b48800428906ae455c2b63acacd44e390e1fee49Romain Guy float r; 167b48800428906ae455c2b63acacd44e390e1fee49Romain Guy float g; 168b48800428906ae455c2b63acacd44e390e1fee49Romain Guy float b; 169b48800428906ae455c2b63acacd44e390e1fee49Romain Guy float a; 170b48800428906ae455c2b63acacd44e390e1fee49Romain Guy }; 171b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 172b48800428906ae455c2b63acacd44e390e1fee49Romain Guy typedef void (GradientCache::*ChannelSplitter)(uint32_t inColor, 173b48800428906ae455c2b63acacd44e390e1fee49Romain Guy GradientColor& outColor) const; 174b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 175b48800428906ae455c2b63acacd44e390e1fee49Romain Guy void splitToBytes(uint32_t inColor, GradientColor& outColor) const; 176b48800428906ae455c2b63acacd44e390e1fee49Romain Guy void splitToFloats(uint32_t inColor, GradientColor& outColor) const; 177b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 178b48800428906ae455c2b63acacd44e390e1fee49Romain Guy typedef void (GradientCache::*ChannelMixer)(GradientColor& start, GradientColor& end, 179b48800428906ae455c2b63acacd44e390e1fee49Romain Guy float amount, uint8_t*& dst) const; 180b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 181b48800428906ae455c2b63acacd44e390e1fee49Romain Guy void mixBytes(GradientColor& start, GradientColor& end, float amount, uint8_t*& dst) const; 182b48800428906ae455c2b63acacd44e390e1fee49Romain Guy void mixFloats(GradientColor& start, GradientColor& end, float amount, uint8_t*& dst) const; 183b48800428906ae455c2b63acacd44e390e1fee49Romain Guy 184059e12ccd20f5c249724a8362d6bac325334ea76Romain Guy LruCache<GradientCacheEntry, Texture*> mCache; 185c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 186c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy uint32_t mSize; 187c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy uint32_t mMaxSize; 188a2341a9f6addcd79723965ec5b1a1c5ae0f8bd65Romain Guy 1898dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy GLint mMaxTextureSize; 190b48800428906ae455c2b63acacd44e390e1fee49Romain Guy bool mUseFloatTexture; 191b48800428906ae455c2b63acacd44e390e1fee49Romain Guy bool mHasNpot; 1928dcfd5e836341b4a803b04d104a930bb312182d3Romain Guy 193fe48f65922d4a3cc4aefe058cee5acec51504a20Romain Guy Vector<SkShader*> mGarbage; 194a2341a9f6addcd79723965ec5b1a1c5ae0f8bd65Romain Guy mutable Mutex mLock; 195c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy}; // class GradientCache 196c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 197c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy}; // namespace uirenderer 198c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy}; // namespace android 199c0ac193b9415680f0a69e20a3f5f22d16f8053beRomain Guy 2005b3b35296e8b2c8d3f07d32bb645d5414db41a1dRomain Guy#endif // ANDROID_HWUI_GRADIENT_CACHE_H 201