• 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 <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 
29 namespace android {
30 namespace uirenderer {
31 
32 struct GradientCacheEntry {
GradientCacheEntryGradientCacheEntry33     GradientCacheEntry() {
34         count = 0;
35         colors = NULL;
36         positions = NULL;
37         tileMode = SkShader::kClamp_TileMode;
38     }
39 
GradientCacheEntryGradientCacheEntry40     GradientCacheEntry(uint32_t* colors, float* positions, int count,
41             SkShader::TileMode tileMode) {
42         copy(colors, positions, count, tileMode);
43     }
44 
GradientCacheEntryGradientCacheEntry45     GradientCacheEntry(const GradientCacheEntry& entry) {
46         copy(entry.colors, entry.positions, entry.count, entry.tileMode);
47     }
48 
~GradientCacheEntryGradientCacheEntry49     ~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;
LTE_INTGradientCacheEntry67         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 
85 private:
86 
copyGradientCacheEntry87     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  */
104 class GradientCache: public OnEntryRemoved<GradientCacheEntry, Texture*> {
105 public:
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 
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             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