• 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 <GLES2/gl2.h>
21 
22 #include <utils/LruCache.h>
23 #include <utils/Mutex.h>
24 #include <utils/Vector.h>
25 
26 #include "Debug.h"
27 #include "Properties.h"
28 #include "Texture.h"
29 #include "utils/Pair.h"
30 
31 class SkBitmap;
32 class SkCanvas;
33 class SkPaint;
34 class SkPath;
35 class SkRect;
36 
37 namespace android {
38 namespace uirenderer {
39 
40 class Caches;
41 
42 ///////////////////////////////////////////////////////////////////////////////
43 // Defines
44 ///////////////////////////////////////////////////////////////////////////////
45 
46 // Debug
47 #if DEBUG_PATHS
48     #define PATH_LOGD(...) ALOGD(__VA_ARGS__)
49 #else
50     #define PATH_LOGD(...)
51 #endif
52 
53 ///////////////////////////////////////////////////////////////////////////////
54 // Classes
55 ///////////////////////////////////////////////////////////////////////////////
56 
57 /**
58  * Alpha texture used to represent a path.
59  */
60 struct PathTexture: public Texture {
PathTexturePathTexture61     PathTexture(Caches& caches): Texture(caches) {
62     }
63 
~PathTexturePathTexture64     ~PathTexture() {
65         clearTask();
66     }
67 
68     /**
69      * Left coordinate of the path bounds.
70      */
71     float left;
72     /**
73      * Top coordinate of the path bounds.
74      */
75     float top;
76     /**
77      * Offset to draw the path at the correct origin.
78      */
79     float offset;
80 
taskPathTexture81     sp<Task<SkBitmap*> > task() const {
82         return mTask;
83     }
84 
setTaskPathTexture85     void setTask(const sp<Task<SkBitmap*> >& task) {
86         mTask = task;
87     }
88 
clearTaskPathTexture89     void clearTask() {
90         if (mTask != NULL) {
91             mTask.clear();
92         }
93     }
94 
95 private:
96     sp<Task<SkBitmap*> > mTask;
97 }; // struct PathTexture
98 
99 enum ShapeType {
100     kShapeNone,
101     kShapeRect,
102     kShapeRoundRect,
103     kShapeCircle,
104     kShapeOval,
105     kShapeArc,
106     kShapePath
107 };
108 
109 struct PathDescription {
110     ShapeType type;
111     SkPaint::Join join;
112     SkPaint::Cap cap;
113     SkPaint::Style style;
114     float miter;
115     float strokeWidth;
116     SkPathEffect* pathEffect;
117     union Shape {
118         struct Path {
119             SkPath* mPath;
120         } path;
121         struct RoundRect {
122             float mWidth;
123             float mHeight;
124             float mRx;
125             float mRy;
126         } roundRect;
127         struct Circle {
128             float mRadius;
129         } circle;
130         struct Oval {
131             float mWidth;
132             float mHeight;
133         } oval;
134         struct Rect {
135             float mWidth;
136             float mHeight;
137         } rect;
138         struct Arc {
139             float mWidth;
140             float mHeight;
141             float mStartAngle;
142             float mSweepAngle;
143             bool mUseCenter;
144         } arc;
145     } shape;
146 
147     PathDescription();
148     PathDescription(ShapeType shapeType, SkPaint* paint);
149 
150     hash_t hash() const;
151 
152     int compare(const PathDescription& rhs) const;
153 
154     bool operator==(const PathDescription& other) const {
155         return compare(other) == 0;
156     }
157 
158     bool operator!=(const PathDescription& other) const {
159         return compare(other) != 0;
160     }
161 
strictly_order_typePathDescription162     friend inline int strictly_order_type(
163             const PathDescription& lhs, const PathDescription& rhs) {
164         return lhs.compare(rhs) < 0;
165     }
166 
compare_typePathDescription167     friend inline int compare_type(const PathDescription& lhs, const PathDescription& rhs) {
168         return lhs.compare(rhs);
169     }
170 
hash_typePathDescription171     friend inline hash_t hash_type(const PathDescription& entry) {
172         return entry.hash();
173     }
174 };
175 
176 /**
177  * A simple LRU shape cache. The cache has a maximum size expressed in bytes.
178  * Any texture added to the cache causing the cache to grow beyond the maximum
179  * allowed size will also cause the oldest texture to be kicked out.
180  */
181 class PathCache: public OnEntryRemoved<PathDescription, PathTexture*> {
182 public:
183     PathCache();
184     ~PathCache();
185 
186     /**
187      * Used as a callback when an entry is removed from the cache.
188      * Do not invoke directly.
189      */
190     void operator()(PathDescription& path, PathTexture*& texture);
191 
192     /**
193      * Clears the cache. This causes all textures to be deleted.
194      */
195     void clear();
196 
197     /**
198      * Sets the maximum size of the cache in bytes.
199      */
200     void setMaxSize(uint32_t maxSize);
201     /**
202      * Returns the maximum size of the cache in bytes.
203      */
204     uint32_t getMaxSize();
205     /**
206      * Returns the current size of the cache in bytes.
207      */
208     uint32_t getSize();
209 
210     PathTexture* getRoundRect(float width, float height, float rx, float ry, SkPaint* paint);
211     PathTexture* getCircle(float radius, SkPaint* paint);
212     PathTexture* getOval(float width, float height, SkPaint* paint);
213     PathTexture* getRect(float width, float height, SkPaint* paint);
214     PathTexture* getArc(float width, float height, float startAngle, float sweepAngle,
215             bool useCenter, SkPaint* paint);
216     PathTexture* get(SkPath* path, SkPaint* paint);
217 
218     /**
219      * Removes the specified path. This is meant to be called from threads
220      * that are not the EGL context thread.
221      */
222     void removeDeferred(SkPath* path);
223     /**
224      * Process deferred removals.
225      */
226     void clearGarbage();
227     /**
228      * Trims the contents of the cache, removing items until it's under its
229      * specified limit.
230      *
231      * Trimming is used for caches that support pre-caching from a worker
232      * thread. During pre-caching the maximum limit of the cache can be
233      * exceeded for the duration of the frame. It is therefore required to
234      * trim the cache at the end of the frame to keep the total amount of
235      * memory used under control.
236      */
237     void trim();
238 
239     /**
240      * Precaches the specified path using background threads.
241      */
242     void precache(SkPath* path, SkPaint* paint);
243 
244     static bool canDrawAsConvexPath(SkPath* path, SkPaint* paint);
245     static void computePathBounds(const SkPath* path, const SkPaint* paint,
246             float& left, float& top, float& offset, uint32_t& width, uint32_t& height);
247     static void computeBounds(const SkRect& bounds, const SkPaint* paint,
248             float& left, float& top, float& offset, uint32_t& width, uint32_t& height);
249 
250 private:
251     typedef Pair<SkPath*, SkPath*> path_pair_t;
252 
253     PathTexture* addTexture(const PathDescription& entry,
254             const SkPath *path, const SkPaint* paint);
255     PathTexture* addTexture(const PathDescription& entry, SkBitmap* bitmap);
256 
257     /**
258      * Generates the texture from a bitmap into the specified texture structure.
259      */
260     void generateTexture(SkBitmap& bitmap, Texture* texture);
261     void generateTexture(const PathDescription& entry, SkBitmap* bitmap, PathTexture* texture,
262             bool addToCache = true);
263 
get(const PathDescription & entry)264     PathTexture* get(const PathDescription& entry) {
265         return mCache.get(entry);
266     }
267 
268     /**
269      * Removes an entry.
270      * The pair must define first=path, second=sourcePath
271      */
272     void remove(Vector<PathDescription>& pathsToRemove, const path_pair_t& pair);
273 
274     /**
275      * Ensures there is enough space in the cache for a texture of the specified
276      * dimensions.
277      */
278     void purgeCache(uint32_t width, uint32_t height);
279 
280     void removeTexture(PathTexture* texture);
281 
checkTextureSize(uint32_t width,uint32_t height)282     bool checkTextureSize(uint32_t width, uint32_t height) {
283         if (width > mMaxTextureSize || height > mMaxTextureSize) {
284             ALOGW("Shape too large to be rendered into a texture (%dx%d, max=%dx%d)",
285                     width, height, mMaxTextureSize, mMaxTextureSize);
286             return false;
287         }
288         return true;
289     }
290 
291     void init();
292 
293     class PathTask: public Task<SkBitmap*> {
294     public:
PathTask(SkPath * path,SkPaint * paint,PathTexture * texture)295         PathTask(SkPath* path, SkPaint* paint, PathTexture* texture):
296             path(path), paint(paint), texture(texture) {
297         }
298 
~PathTask()299         ~PathTask() {
300             delete future()->get();
301         }
302 
303         SkPath* path;
304         SkPaint* paint;
305         PathTexture* texture;
306     };
307 
308     class PathProcessor: public TaskProcessor<SkBitmap*> {
309     public:
310         PathProcessor(Caches& caches);
~PathProcessor()311         ~PathProcessor() { }
312 
313         virtual void onProcess(const sp<Task<SkBitmap*> >& task);
314 
315     private:
316         uint32_t mMaxTextureSize;
317     };
318 
319     LruCache<PathDescription, PathTexture*> mCache;
320     uint32_t mSize;
321     uint32_t mMaxSize;
322     GLuint mMaxTextureSize;
323 
324     bool mDebugEnabled;
325 
326     sp<PathProcessor> mProcessor;
327 
328     Vector<path_pair_t> mGarbage;
329     mutable Mutex mLock;
330 }; // class PathCache
331 
332 }; // namespace uirenderer
333 }; // namespace android
334 
335 #endif // ANDROID_HWUI_PATH_CACHE_H
336