• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <memory>
21 
22 #include <GLES3/gl3.h>
23 
24 #include <SkShader.h>
25 
26 #include <utils/LruCache.h>
27 #include <utils/Mutex.h>
28 #include <utils/Vector.h>
29 
30 namespace android {
31 namespace uirenderer {
32 
33 class Texture;
34 
35 struct GradientCacheEntry {
GradientCacheEntryGradientCacheEntry36     GradientCacheEntry() {
37         count = 0;
38         colors = nullptr;
39         positions = nullptr;
40     }
41 
GradientCacheEntryGradientCacheEntry42     GradientCacheEntry(uint32_t* colors, float* positions, uint32_t count) {
43         copy(colors, positions, count);
44     }
45 
GradientCacheEntryGradientCacheEntry46     GradientCacheEntry(const GradientCacheEntry& entry) {
47         copy(entry.colors.get(), entry.positions.get(), entry.count);
48     }
49 
50     GradientCacheEntry& operator=(const GradientCacheEntry& entry) {
51         if (this != &entry) {
52             copy(entry.colors.get(), entry.positions.get(), entry.count);
53         }
54 
55         return *this;
56     }
57 
58     hash_t hash() const;
59 
60     static int compare(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs);
61 
62     bool operator==(const GradientCacheEntry& other) const {
63         return compare(*this, other) == 0;
64     }
65 
66     bool operator!=(const GradientCacheEntry& other) const {
67         return compare(*this, other) != 0;
68     }
69 
70     std::unique_ptr<uint32_t[]> colors;
71     std::unique_ptr<float[]> positions;
72     uint32_t count;
73 
74 private:
copyGradientCacheEntry75     void copy(uint32_t* colors, float* positions, uint32_t count) {
76         this->count = count;
77         this->colors.reset(new uint32_t[count]);
78         this->positions.reset(new float[count]);
79 
80         memcpy(this->colors.get(), colors, count * sizeof(uint32_t));
81         memcpy(this->positions.get(), positions, count * sizeof(float));
82     }
83 
84 }; // GradientCacheEntry
85 
86 // Caching support
87 
strictly_order_type(const GradientCacheEntry & lhs,const GradientCacheEntry & rhs)88 inline int strictly_order_type(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs) {
89     return GradientCacheEntry::compare(lhs, rhs) < 0;
90 }
91 
compare_type(const GradientCacheEntry & lhs,const GradientCacheEntry & rhs)92 inline int compare_type(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs) {
93     return GradientCacheEntry::compare(lhs, rhs);
94 }
95 
hash_type(const GradientCacheEntry & entry)96 inline hash_t hash_type(const GradientCacheEntry& entry) {
97     return entry.hash();
98 }
99 
100 /**
101  * A simple LRU gradient cache. The cache has a maximum size expressed in bytes.
102  * Any texture added to the cache causing the cache to grow beyond the maximum
103  * allowed size will also cause the oldest texture to be kicked out.
104  */
105 class GradientCache: public OnEntryRemoved<GradientCacheEntry, Texture*> {
106 public:
107     GradientCache(Extensions& extensions);
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) override;
115 
116     /**
117      * Returns the texture associated with the specified shader.
118      */
119     Texture* get(uint32_t* colors, float* positions, int count);
120 
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 
139 private:
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 
147     void generateTexture(uint32_t* colors, float* positions, Texture* texture);
148 
149     struct GradientInfo {
150         uint32_t width;
151         bool hasAlpha;
152     };
153 
154     void getGradientInfo(const uint32_t* colors, const int count, GradientInfo& info);
155 
156     size_t bytesPerPixel() const;
157 
158     struct GradientColor {
159         float r;
160         float g;
161         float b;
162         float a;
163     };
164 
165     typedef void (GradientCache::*ChannelSplitter)(uint32_t inColor,
166             GradientColor& outColor) const;
167 
168     void splitToBytes(uint32_t inColor, GradientColor& outColor) const;
169     void splitToFloats(uint32_t inColor, GradientColor& outColor) const;
170 
171     typedef void (GradientCache::*ChannelMixer)(GradientColor& start, GradientColor& end,
172             float amount, uint8_t*& dst) const;
173 
174     void mixBytes(GradientColor& start, GradientColor& end, float amount, uint8_t*& dst) const;
175     void mixFloats(GradientColor& start, GradientColor& end, float amount, uint8_t*& dst) const;
176 
177     LruCache<GradientCacheEntry, Texture*> mCache;
178 
179     uint32_t mSize;
180     uint32_t mMaxSize;
181 
182     GLint mMaxTextureSize;
183     bool mUseFloatTexture;
184     bool mHasNpot;
185 
186     Vector<SkShader*> mGarbage;
187     mutable Mutex mLock;
188 }; // class GradientCache
189 
190 }; // namespace uirenderer
191 }; // namespace android
192 
193 #endif // ANDROID_HWUI_GRADIENT_CACHE_H
194