• 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 
29 #include "FloatColor.h"
30 
31 namespace android {
32 namespace uirenderer {
33 
34 class Texture;
35 
36 struct GradientCacheEntry {
GradientCacheEntryGradientCacheEntry37     GradientCacheEntry() {
38         count = 0;
39         colors = nullptr;
40         positions = nullptr;
41     }
42 
GradientCacheEntryGradientCacheEntry43     GradientCacheEntry(uint32_t* colors, float* positions, uint32_t count) {
44         copy(colors, positions, count);
45     }
46 
GradientCacheEntryGradientCacheEntry47     GradientCacheEntry(const GradientCacheEntry& entry) {
48         copy(entry.colors.get(), entry.positions.get(), entry.count);
49     }
50 
51     GradientCacheEntry& operator=(const GradientCacheEntry& entry) {
52         if (this != &entry) {
53             copy(entry.colors.get(), entry.positions.get(), entry.count);
54         }
55 
56         return *this;
57     }
58 
59     hash_t hash() const;
60 
61     static int compare(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs);
62 
63     bool operator==(const GradientCacheEntry& other) const { return compare(*this, other) == 0; }
64 
65     bool operator!=(const GradientCacheEntry& other) const { return compare(*this, other) != 0; }
66 
67     std::unique_ptr<uint32_t[]> colors;
68     std::unique_ptr<float[]> positions;
69     uint32_t count;
70 
71 private:
copyGradientCacheEntry72     void copy(uint32_t* colors, float* positions, uint32_t count) {
73         this->count = count;
74         this->colors.reset(new uint32_t[count]);
75         this->positions.reset(new float[count]);
76 
77         memcpy(this->colors.get(), colors, count * sizeof(uint32_t));
78         memcpy(this->positions.get(), positions, count * sizeof(float));
79     }
80 
81 };  // GradientCacheEntry
82 
83 // Caching support
84 
strictly_order_type(const GradientCacheEntry & lhs,const GradientCacheEntry & rhs)85 inline int strictly_order_type(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs) {
86     return GradientCacheEntry::compare(lhs, rhs) < 0;
87 }
88 
compare_type(const GradientCacheEntry & lhs,const GradientCacheEntry & rhs)89 inline int compare_type(const GradientCacheEntry& lhs, const GradientCacheEntry& rhs) {
90     return GradientCacheEntry::compare(lhs, rhs);
91 }
92 
hash_type(const GradientCacheEntry & entry)93 inline hash_t hash_type(const GradientCacheEntry& entry) {
94     return entry.hash();
95 }
96 
97 /**
98  * A simple LRU gradient cache. The cache has a maximum size expressed in bytes.
99  * Any texture added to the cache causing the cache to grow beyond the maximum
100  * allowed size will also cause the oldest texture to be kicked out.
101  */
102 class GradientCache : public OnEntryRemoved<GradientCacheEntry, Texture*> {
103 public:
104     explicit GradientCache(const Extensions& extensions);
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) override;
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      * Returns the maximum size of the cache in bytes.
125      */
126     uint32_t getMaxSize();
127     /**
128      * Returns the current size of the cache in bytes.
129      */
130     uint32_t getSize();
131 
132 private:
133     /**
134      * Adds a new linear gradient to the cache. The generated texture is
135      * returned.
136      */
137     Texture* addLinearGradient(GradientCacheEntry& gradient, uint32_t* colors, float* positions,
138                                int count);
139 
140     void generateTexture(uint32_t* colors, float* positions, const uint32_t width,
141                          const uint32_t height, Texture* texture);
142 
143     struct GradientInfo {
144         uint32_t width;
145         bool hasAlpha;
146     };
147 
148     void getGradientInfo(const uint32_t* colors, const int count, GradientInfo& info);
149 
150     size_t bytesPerPixel() const;
151     size_t sourceBytesPerPixel() const;
152 
153     typedef void (GradientCache::*ChannelMixer)(const FloatColor& start, const FloatColor& end,
154                                                 float amount, uint8_t*& dst) const;
155 
156     void mixBytes(const FloatColor& start, const FloatColor& end, float amount,
157                   uint8_t*& dst) const;
158     void mixFloats(const FloatColor& start, const FloatColor& end, float amount,
159                    uint8_t*& dst) const;
160 
161     LruCache<GradientCacheEntry, Texture*> mCache;
162 
163     uint32_t mSize;
164     const uint32_t mMaxSize;
165 
166     GLint mMaxTextureSize;
167     bool mUseFloatTexture;
168     bool mHasNpot;
169     bool mHasLinearBlending;
170 
171     mutable Mutex mLock;
172 };  // class GradientCache
173 
174 };  // namespace uirenderer
175 };  // namespace android
176 
177 #endif  // ANDROID_HWUI_GRADIENT_CACHE_H
178