blob: 3efeaf64d4866111a8b65185661be612c9f37a1d [file] [log] [blame]
Chris Craik05f3d6e2014-06-02 16:27:04 -07001/*
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_TESSELLATION_CACHE_H
18#define ANDROID_HWUI_TESSELLATION_CACHE_H
19
20#include <utils/LruCache.h>
21#include <utils/Mutex.h>
22#include <utils/Vector.h>
23
24#include "Debug.h"
25#include "utils/Macros.h"
26#include "utils/Pair.h"
Chris Craik05f3d6e2014-06-02 16:27:04 -070027
28class SkBitmap;
29class SkCanvas;
30class SkPaint;
31class SkPath;
32struct SkRect;
33
34namespace android {
35namespace uirenderer {
36
37class Caches;
Tom Hudson2dc236b2014-10-15 15:46:42 -040038class VertexBuffer;
Chris Craik05f3d6e2014-06-02 16:27:04 -070039
40///////////////////////////////////////////////////////////////////////////////
41// Classes
42///////////////////////////////////////////////////////////////////////////////
43
44class TessellationCache {
45public:
46 typedef Pair<VertexBuffer*, VertexBuffer*> vertexBuffer_pair_t;
47
48 struct Description {
49 DESCRIPTION_TYPE(Description);
50 enum Type {
51 kNone,
52 kRoundRect,
Chris Craik05f3d6e2014-06-02 16:27:04 -070053 };
54
55 Type type;
Chris Craik6ac174b2014-06-17 13:47:05 -070056 float scaleX;
57 float scaleY;
Chris Craiked4ef0b2014-06-12 13:27:30 -070058 bool aa;
Chris Craik05f3d6e2014-06-02 16:27:04 -070059 SkPaint::Cap cap;
60 SkPaint::Style style;
61 float strokeWidth;
62 union Shape {
63 struct RoundRect {
Chris Craik6ac174b2014-06-17 13:47:05 -070064 float width;
65 float height;
66 float rx;
67 float ry;
Chris Craik05f3d6e2014-06-02 16:27:04 -070068 } roundRect;
69 } shape;
70
71 Description();
Chris Craik6ac174b2014-06-17 13:47:05 -070072 Description(Type type, const Matrix4& transform, const SkPaint& paint);
Chris Craik05f3d6e2014-06-02 16:27:04 -070073 hash_t hash() const;
Chris Craik6ac174b2014-06-17 13:47:05 -070074 void setupMatrixAndPaint(Matrix4* matrix, SkPaint* paint) const;
Chris Craik05f3d6e2014-06-02 16:27:04 -070075 };
76
77 struct ShadowDescription {
78 DESCRIPTION_TYPE(ShadowDescription);
79 const void* nodeKey;
80 float matrixData[16];
81
82 ShadowDescription();
83 ShadowDescription(const void* nodeKey, const Matrix4* drawTransform);
84 hash_t hash() const;
85 };
86
87 TessellationCache();
88 ~TessellationCache();
89
90 /**
91 * Clears the cache. This causes all TessellationBuffers to be deleted.
92 */
93 void clear();
94
95 /**
96 * Sets the maximum size of the cache in bytes.
97 */
98 void setMaxSize(uint32_t maxSize);
99 /**
100 * Returns the maximum size of the cache in bytes.
101 */
102 uint32_t getMaxSize();
103 /**
104 * Returns the current size of the cache in bytes.
105 */
106 uint32_t getSize();
107
108 /**
109 * Trims the contents of the cache, removing items until it's under its
110 * specified limit.
111 *
112 * Trimming is used for caches that support pre-caching from a worker
113 * thread. During pre-caching the maximum limit of the cache can be
114 * exceeded for the duration of the frame. It is therefore required to
115 * trim the cache at the end of the frame to keep the total amount of
116 * memory used under control.
117 *
118 * Also removes transient Shadow VertexBuffers, which aren't cached between frames.
119 */
120 void trim();
121
122 // TODO: precache/get for Oval, Lines, Points, etc.
123
Chris Craik6ac174b2014-06-17 13:47:05 -0700124 void precacheRoundRect(const Matrix4& transform, const SkPaint& paint,
125 float width, float height, float rx, float ry) {
126 getRoundRectBuffer(transform, paint, width, height, rx, ry);
Chris Craik05f3d6e2014-06-02 16:27:04 -0700127 }
Chris Craik6ac174b2014-06-17 13:47:05 -0700128 const VertexBuffer* getRoundRect(const Matrix4& transform, const SkPaint& paint,
129 float width, float height, float rx, float ry);
Chris Craik05f3d6e2014-06-02 16:27:04 -0700130
131 void precacheShadows(const Matrix4* drawTransform, const Rect& localClip,
132 bool opaque, const SkPath* casterPerimeter,
133 const Matrix4* transformXY, const Matrix4* transformZ,
134 const Vector3& lightCenter, float lightRadius);
135
136 void getShadowBuffers(const Matrix4* drawTransform, const Rect& localClip,
137 bool opaque, const SkPath* casterPerimeter,
138 const Matrix4* transformXY, const Matrix4* transformZ,
139 const Vector3& lightCenter, float lightRadius,
140 vertexBuffer_pair_t& outBuffers);
141
142private:
143 class Buffer;
144 class TessellationTask;
145 class TessellationProcessor;
146
Chris Craik6ac174b2014-06-17 13:47:05 -0700147 typedef VertexBuffer* (*Tessellator)(const Description&);
Chris Craik05f3d6e2014-06-02 16:27:04 -0700148
Chris Craik6ac174b2014-06-17 13:47:05 -0700149 Buffer* getRectBuffer(const Matrix4& transform, const SkPaint& paint,
150 float width, float height);
151 Buffer* getRoundRectBuffer(const Matrix4& transform, const SkPaint& paint,
152 float width, float height, float rx, float ry);
Chris Craik05f3d6e2014-06-02 16:27:04 -0700153
Chris Craik6ac174b2014-06-17 13:47:05 -0700154 Buffer* getOrCreateBuffer(const Description& entry, Tessellator tessellator);
Chris Craik05f3d6e2014-06-02 16:27:04 -0700155
156 uint32_t mSize;
157 uint32_t mMaxSize;
158
159 bool mDebugEnabled;
160
161 mutable Mutex mLock;
162
163 ///////////////////////////////////////////////////////////////////////////////
164 // General tessellation caching
165 ///////////////////////////////////////////////////////////////////////////////
166 sp<TaskProcessor<VertexBuffer*> > mProcessor;
167 LruCache<Description, Buffer*> mCache;
168 class BufferRemovedListener : public OnEntryRemoved<Description, Buffer*> {
Chris Craike84a2082014-12-22 14:28:49 -0800169 void operator()(Description& description, Buffer*& buffer) override;
Chris Craik05f3d6e2014-06-02 16:27:04 -0700170 };
171 BufferRemovedListener mBufferRemovedListener;
172
173 ///////////////////////////////////////////////////////////////////////////////
174 // Shadow tessellation caching
175 ///////////////////////////////////////////////////////////////////////////////
176 sp<TaskProcessor<vertexBuffer_pair_t*> > mShadowProcessor;
177
178 // holds a pointer, and implicit strong ref to each shadow task of the frame
179 LruCache<ShadowDescription, Task<vertexBuffer_pair_t*>*> mShadowCache;
180 class BufferPairRemovedListener : public OnEntryRemoved<ShadowDescription, Task<vertexBuffer_pair_t*>*> {
Chris Craike84a2082014-12-22 14:28:49 -0800181 void operator()(ShadowDescription& description, Task<vertexBuffer_pair_t*>*& bufferPairTask) override {
182 bufferPairTask->decStrong(nullptr);
Chris Craik05f3d6e2014-06-02 16:27:04 -0700183 }
184 };
185 BufferPairRemovedListener mBufferPairRemovedListener;
186
187}; // class TessellationCache
188
189}; // namespace uirenderer
190}; // namespace android
191
192#endif // ANDROID_HWUI_PATH_CACHE_H