• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 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_PATH_CACHE_H
18 #define ANDROID_HWUI_PATH_CACHE_H
19 
20 #include "Debug.h"
21 #include "Texture.h"
22 #include "hwui/Bitmap.h"
23 #include "thread/Task.h"
24 #include "thread/TaskProcessor.h"
25 #include "utils/Macros.h"
26 #include "utils/Pair.h"
27 
28 #include <GLES2/gl2.h>
29 #include <SkPaint.h>
30 #include <SkPath.h>
31 #include <utils/LruCache.h>
32 #include <utils/Mutex.h>
33 
34 #include <vector>
35 
36 class SkCanvas;
37 class SkPaint;
38 struct SkRect;
39 
40 namespace android {
41 namespace uirenderer {
42 
43 class Caches;
44 ///////////////////////////////////////////////////////////////////////////////
45 // Defines
46 ///////////////////////////////////////////////////////////////////////////////
47 
48 // Debug
49 #if DEBUG_PATHS
50 #define PATH_LOGD(...) ALOGD(__VA_ARGS__)
51 #else
52 #define PATH_LOGD(...)
53 #endif
54 
55 ///////////////////////////////////////////////////////////////////////////////
56 // Classes
57 ///////////////////////////////////////////////////////////////////////////////
58 
59 struct PathTexture;
60 class PathTask : public Task<sk_sp<Bitmap>> {
61 public:
PathTask(const SkPath * path,const SkPaint * paint,PathTexture * texture)62     PathTask(const SkPath* path, const SkPaint* paint, PathTexture* texture)
63             : path(*path), paint(*paint), texture(texture) {}
64 
65     // copied, since input path not guaranteed to survive for duration of task
66     const SkPath path;
67 
68     // copied, since input paint may not be immutable
69     const SkPaint paint;
70     PathTexture* texture;
71 };
72 
73 /**
74  * Alpha texture used to represent a path.
75  */
76 struct PathTexture : public Texture {
PathTexturePathTexture77     PathTexture(Caches& caches, int generation) : Texture(caches) { this->generation = generation; }
78 
~PathTexturePathTexture79     ~PathTexture() { clearTask(); }
80 
81     /**
82      * Left coordinate of the path bounds.
83      */
84     float left = 0;
85     /**
86      * Top coordinate of the path bounds.
87      */
88     float top = 0;
89     /**
90      * Offset to draw the path at the correct origin.
91      */
92     float offset = 0;
93 
taskPathTexture94     sp<PathTask> task() const { return mTask; }
95 
setTaskPathTexture96     void setTask(const sp<PathTask>& task) { mTask = task; }
97 
clearTaskPathTexture98     void clearTask() {
99         if (mTask != nullptr) {
100             mTask.clear();
101         }
102     }
103 
104 private:
105     sp<PathTask> mTask;
106 };  // struct PathTexture
107 
108 enum class ShapeType { None, Rect, RoundRect, Circle, Oval, Arc, Path };
109 
110 struct PathDescription {
111     HASHABLE_TYPE(PathDescription);
112     ShapeType type;
113     SkPaint::Join join;
114     SkPaint::Cap cap;
115     SkPaint::Style style;
116     float miter;
117     float strokeWidth;
118     SkPathEffect* pathEffect;
119     union Shape {
120         struct Path {
121             uint32_t mGenerationID;
122         } path;
123         struct RoundRect {
124             float mWidth;
125             float mHeight;
126             float mRx;
127             float mRy;
128         } roundRect;
129         struct Circle {
130             float mRadius;
131         } circle;
132         struct Oval {
133             float mWidth;
134             float mHeight;
135         } oval;
136         struct Rect {
137             float mWidth;
138             float mHeight;
139         } rect;
140         struct Arc {
141             float mWidth;
142             float mHeight;
143             float mStartAngle;
144             float mSweepAngle;
145             bool mUseCenter;
146         } arc;
147     } shape;
148 
149     PathDescription();
150     PathDescription(ShapeType shapeType, const SkPaint* paint);
151 };
152 
153 /**
154  * A simple LRU shape cache. The cache has a maximum size expressed in bytes.
155  * Any texture added to the cache causing the cache to grow beyond the maximum
156  * allowed size will also cause the oldest texture to be kicked out.
157  */
158 class PathCache : public OnEntryRemoved<PathDescription, PathTexture*> {
159 public:
160     PathCache();
161     ~PathCache();
162 
163     /**
164      * Used as a callback when an entry is removed from the cache.
165      * Do not invoke directly.
166      */
167     void operator()(PathDescription& path, PathTexture*& texture) override;
168 
169     /**
170      * Clears the cache. This causes all textures to be deleted.
171      */
172     void clear();
173 
174     /**
175      * Returns the maximum size of the cache in bytes.
176      */
177     uint32_t getMaxSize();
178     /**
179      * Returns the current size of the cache in bytes.
180      */
181     uint32_t getSize();
182 
183     PathTexture* getRoundRect(float width, float height, float rx, float ry, const SkPaint* paint);
184     PathTexture* getCircle(float radius, const SkPaint* paint);
185     PathTexture* getOval(float width, float height, const SkPaint* paint);
186     PathTexture* getRect(float width, float height, const SkPaint* paint);
187     PathTexture* getArc(float width, float height, float startAngle, float sweepAngle,
188                         bool useCenter, const SkPaint* paint);
189     PathTexture* get(const SkPath* path, const SkPaint* paint);
190     void remove(const SkPath* path, const SkPaint* paint);
191 
192     /**
193      * Removes the specified path. This is meant to be called from threads
194      * that are not the EGL context thread.
195      */
196     ANDROID_API void removeDeferred(const SkPath* path);
197     /**
198      * Process deferred removals.
199      */
200     void clearGarbage();
201     /**
202      * Trims the contents of the cache, removing items until it's under its
203      * specified limit.
204      *
205      * Trimming is used for caches that support pre-caching from a worker
206      * thread. During pre-caching the maximum limit of the cache can be
207      * exceeded for the duration of the frame. It is therefore required to
208      * trim the cache at the end of the frame to keep the total amount of
209      * memory used under control.
210      */
211     void trim();
212 
213     /**
214      * Precaches the specified path using background threads.
215      */
216     void precache(const SkPath* path, const SkPaint* paint);
217 
218 private:
219     PathTexture* addTexture(const PathDescription& entry, const SkPath* path, const SkPaint* paint);
220 
221     /**
222      * Generates the texture from a bitmap into the specified texture structure.
223      */
224     void generateTexture(Bitmap& bitmap, Texture* texture);
225     void generateTexture(const PathDescription& entry, Bitmap& bitmap, PathTexture* texture,
226                          bool addToCache = true);
227 
get(const PathDescription & entry)228     PathTexture* get(const PathDescription& entry) { return mCache.get(entry); }
229 
230     /**
231      * Ensures there is enough space in the cache for a texture of the specified
232      * dimensions.
233      */
234     void purgeCache(uint32_t width, uint32_t height);
235 
236     void removeTexture(PathTexture* texture);
237 
238     void init();
239 
240     class PathProcessor : public TaskProcessor<sk_sp<Bitmap>> {
241     public:
242         explicit PathProcessor(Caches& caches);
~PathProcessor()243         ~PathProcessor() {}
244 
245         virtual void onProcess(const sp<Task<sk_sp<Bitmap>>>& task) override;
246 
247     private:
248         uint32_t mMaxTextureSize;
249     };
250 
251     LruCache<PathDescription, PathTexture*> mCache;
252     uint32_t mSize;
253     const uint32_t mMaxSize;
254     GLuint mMaxTextureSize;
255 
256     bool mDebugEnabled;
257 
258     sp<PathProcessor> mProcessor;
259 
260     std::vector<uint32_t> mGarbage;
261     mutable Mutex mLock;
262 };  // class PathCache
263 
264 };  // namespace uirenderer
265 };  // namespace android
266 
267 #endif  // ANDROID_HWUI_PATH_CACHE_H
268