blob: 6141b4ef63d70423ac878fca04dd42f3291c9308 [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
Chris Craik05f3d6e2014-06-02 16:27:04 -070020#include "Debug.h"
John Reck82f5e0c2015-10-22 17:07:45 -070021#include "Matrix.h"
22#include "Rect.h"
23#include "Vector.h"
Chris Craikd8165e82016-02-03 15:52:25 -080024#include "VertexBuffer.h"
John Reck82f5e0c2015-10-22 17:07:45 -070025#include "thread/TaskProcessor.h"
Chris Craik05f3d6e2014-06-02 16:27:04 -070026#include "utils/Macros.h"
27#include "utils/Pair.h"
Chris Craik05f3d6e2014-06-02 16:27:04 -070028
John Reck82f5e0c2015-10-22 17:07:45 -070029#include <SkPaint.h>
Chris Craik6e068c012016-01-15 16:15:30 -080030#include <SkPath.h>
John Reck82f5e0c2015-10-22 17:07:45 -070031
32#include <utils/LruCache.h>
33#include <utils/Mutex.h>
34#include <utils/StrongPointer.h>
35
Chris Craik05f3d6e2014-06-02 16:27:04 -070036class SkBitmap;
37class SkCanvas;
Chris Craik05f3d6e2014-06-02 16:27:04 -070038struct SkRect;
39
40namespace android {
41namespace uirenderer {
42
43class Caches;
Tom Hudson2dc236b2014-10-15 15:46:42 -040044class VertexBuffer;
Chris Craik05f3d6e2014-06-02 16:27:04 -070045
46///////////////////////////////////////////////////////////////////////////////
47// Classes
48///////////////////////////////////////////////////////////////////////////////
49
50class TessellationCache {
51public:
52 typedef Pair<VertexBuffer*, VertexBuffer*> vertexBuffer_pair_t;
53
54 struct Description {
sergeyv7224e2b2016-04-07 18:06:53 -070055 HASHABLE_TYPE(Description);
56 enum class Type {
57 None,
58 RoundRect,
Chris Craik05f3d6e2014-06-02 16:27:04 -070059 };
60
61 Type type;
Chris Craik6ac174b2014-06-17 13:47:05 -070062 float scaleX;
63 float scaleY;
Chris Craiked4ef0b2014-06-12 13:27:30 -070064 bool aa;
Chris Craik05f3d6e2014-06-02 16:27:04 -070065 SkPaint::Cap cap;
66 SkPaint::Style style;
67 float strokeWidth;
68 union Shape {
69 struct RoundRect {
Chris Craik6ac174b2014-06-17 13:47:05 -070070 float width;
71 float height;
72 float rx;
73 float ry;
Chris Craik05f3d6e2014-06-02 16:27:04 -070074 } roundRect;
75 } shape;
76
77 Description();
Chris Craik6ac174b2014-06-17 13:47:05 -070078 Description(Type type, const Matrix4& transform, const SkPaint& paint);
Chris Craik6ac174b2014-06-17 13:47:05 -070079 void setupMatrixAndPaint(Matrix4* matrix, SkPaint* paint) const;
Chris Craik05f3d6e2014-06-02 16:27:04 -070080 };
81
82 struct ShadowDescription {
sergeyv7224e2b2016-04-07 18:06:53 -070083 HASHABLE_TYPE(ShadowDescription);
84 const SkPath* nodeKey;
Chris Craik05f3d6e2014-06-02 16:27:04 -070085 float matrixData[16];
86
87 ShadowDescription();
sergeyv7224e2b2016-04-07 18:06:53 -070088 ShadowDescription(const SkPath* nodeKey, const Matrix4* drawTransform);
Chris Craik05f3d6e2014-06-02 16:27:04 -070089 };
90
Chris Craikd8165e82016-02-03 15:52:25 -080091 class ShadowTask : public Task<vertexBuffer_pair_t> {
Chris Craik6e068c012016-01-15 16:15:30 -080092 public:
93 ShadowTask(const Matrix4* drawTransform, const Rect& localClip, bool opaque,
94 const SkPath* casterPerimeter, const Matrix4* transformXY, const Matrix4* transformZ,
95 const Vector3& lightCenter, float lightRadius)
96 : drawTransform(*drawTransform)
97 , localClip(localClip)
98 , opaque(opaque)
99 , casterPerimeter(*casterPerimeter)
100 , transformXY(*transformXY)
101 , transformZ(*transformZ)
102 , lightCenter(lightCenter)
103 , lightRadius(lightRadius) {
104 }
105
Chris Craik6e068c012016-01-15 16:15:30 -0800106 /* Note - we deep copy all task parameters, because *even though* pointers into Allocator
107 * controlled objects (like the SkPath and Matrix4s) should be safe for the entire frame,
108 * certain Allocators are destroyed before trim() is called to flush incomplete tasks.
109 *
Chris Craikd8165e82016-02-03 15:52:25 -0800110 * These deep copies could be avoided, long term, by canceling or flushing outstanding
Chris Craik6e068c012016-01-15 16:15:30 -0800111 * tasks before tearing down single-frame LinearAllocators.
112 */
113 const Matrix4 drawTransform;
114 const Rect localClip;
115 bool opaque;
116 const SkPath casterPerimeter;
117 const Matrix4 transformXY;
118 const Matrix4 transformZ;
119 const Vector3 lightCenter;
120 const float lightRadius;
Chris Craikd8165e82016-02-03 15:52:25 -0800121 VertexBuffer ambientBuffer;
122 VertexBuffer spotBuffer;
Chris Craik6e068c012016-01-15 16:15:30 -0800123 };
124
Chris Craik05f3d6e2014-06-02 16:27:04 -0700125 TessellationCache();
126 ~TessellationCache();
127
128 /**
129 * Clears the cache. This causes all TessellationBuffers to be deleted.
130 */
131 void clear();
Chris Craik05f3d6e2014-06-02 16:27:04 -0700132 /**
133 * Returns the maximum size of the cache in bytes.
134 */
135 uint32_t getMaxSize();
136 /**
137 * Returns the current size of the cache in bytes.
138 */
139 uint32_t getSize();
140
141 /**
142 * Trims the contents of the cache, removing items until it's under its
143 * specified limit.
144 *
145 * Trimming is used for caches that support pre-caching from a worker
146 * thread. During pre-caching the maximum limit of the cache can be
147 * exceeded for the duration of the frame. It is therefore required to
148 * trim the cache at the end of the frame to keep the total amount of
149 * memory used under control.
150 *
151 * Also removes transient Shadow VertexBuffers, which aren't cached between frames.
152 */
153 void trim();
154
155 // TODO: precache/get for Oval, Lines, Points, etc.
156
Chris Craik6ac174b2014-06-17 13:47:05 -0700157 void precacheRoundRect(const Matrix4& transform, const SkPaint& paint,
158 float width, float height, float rx, float ry) {
159 getRoundRectBuffer(transform, paint, width, height, rx, ry);
Chris Craik05f3d6e2014-06-02 16:27:04 -0700160 }
Chris Craik6ac174b2014-06-17 13:47:05 -0700161 const VertexBuffer* getRoundRect(const Matrix4& transform, const SkPaint& paint,
162 float width, float height, float rx, float ry);
Chris Craik05f3d6e2014-06-02 16:27:04 -0700163
Chris Craik6e068c012016-01-15 16:15:30 -0800164 // TODO: delete these when switching to HWUI_NEW_OPS
Chris Craik05f3d6e2014-06-02 16:27:04 -0700165 void precacheShadows(const Matrix4* drawTransform, const Rect& localClip,
166 bool opaque, const SkPath* casterPerimeter,
167 const Matrix4* transformXY, const Matrix4* transformZ,
168 const Vector3& lightCenter, float lightRadius);
Chris Craik05f3d6e2014-06-02 16:27:04 -0700169 void getShadowBuffers(const Matrix4* drawTransform, const Rect& localClip,
170 bool opaque, const SkPath* casterPerimeter,
171 const Matrix4* transformXY, const Matrix4* transformZ,
172 const Vector3& lightCenter, float lightRadius,
173 vertexBuffer_pair_t& outBuffers);
174
Chris Craik6e068c012016-01-15 16:15:30 -0800175 sp<ShadowTask> getShadowTask(const Matrix4* drawTransform, const Rect& localClip,
176 bool opaque, const SkPath* casterPerimeter,
177 const Matrix4* transformXY, const Matrix4* transformZ,
178 const Vector3& lightCenter, float lightRadius);
179
Chris Craik05f3d6e2014-06-02 16:27:04 -0700180private:
181 class Buffer;
182 class TessellationTask;
183 class TessellationProcessor;
184
Chris Craik6ac174b2014-06-17 13:47:05 -0700185 typedef VertexBuffer* (*Tessellator)(const Description&);
Chris Craik05f3d6e2014-06-02 16:27:04 -0700186
Chris Craik6ac174b2014-06-17 13:47:05 -0700187 Buffer* getRectBuffer(const Matrix4& transform, const SkPaint& paint,
188 float width, float height);
189 Buffer* getRoundRectBuffer(const Matrix4& transform, const SkPaint& paint,
190 float width, float height, float rx, float ry);
Chris Craik05f3d6e2014-06-02 16:27:04 -0700191
Chris Craik6ac174b2014-06-17 13:47:05 -0700192 Buffer* getOrCreateBuffer(const Description& entry, Tessellator tessellator);
Chris Craik05f3d6e2014-06-02 16:27:04 -0700193
Chris Craik48a8f432016-02-05 15:59:29 -0800194 const uint32_t mMaxSize;
Chris Craik05f3d6e2014-06-02 16:27:04 -0700195
196 bool mDebugEnabled;
197
198 mutable Mutex mLock;
199
200 ///////////////////////////////////////////////////////////////////////////////
201 // General tessellation caching
202 ///////////////////////////////////////////////////////////////////////////////
203 sp<TaskProcessor<VertexBuffer*> > mProcessor;
204 LruCache<Description, Buffer*> mCache;
205 class BufferRemovedListener : public OnEntryRemoved<Description, Buffer*> {
Chris Craike84a2082014-12-22 14:28:49 -0800206 void operator()(Description& description, Buffer*& buffer) override;
Chris Craik05f3d6e2014-06-02 16:27:04 -0700207 };
208 BufferRemovedListener mBufferRemovedListener;
209
210 ///////////////////////////////////////////////////////////////////////////////
211 // Shadow tessellation caching
212 ///////////////////////////////////////////////////////////////////////////////
Chris Craikd8165e82016-02-03 15:52:25 -0800213 sp<TaskProcessor<vertexBuffer_pair_t> > mShadowProcessor;
Chris Craik05f3d6e2014-06-02 16:27:04 -0700214
215 // holds a pointer, and implicit strong ref to each shadow task of the frame
Chris Craikd8165e82016-02-03 15:52:25 -0800216 LruCache<ShadowDescription, Task<vertexBuffer_pair_t>*> mShadowCache;
217 class BufferPairRemovedListener : public OnEntryRemoved<ShadowDescription, Task<vertexBuffer_pair_t>*> {
218 void operator()(ShadowDescription& description, Task<vertexBuffer_pair_t>*& bufferPairTask) override {
Chris Craike84a2082014-12-22 14:28:49 -0800219 bufferPairTask->decStrong(nullptr);
Chris Craik05f3d6e2014-06-02 16:27:04 -0700220 }
221 };
222 BufferPairRemovedListener mBufferPairRemovedListener;
223
224}; // class TessellationCache
225
John Reck82f5e0c2015-10-22 17:07:45 -0700226void tessellateShadows(
227 const Matrix4* drawTransform, const Rect* localClip,
228 bool isCasterOpaque, const SkPath* casterPerimeter,
229 const Matrix4* casterTransformXY, const Matrix4* casterTransformZ,
230 const Vector3& lightCenter, float lightRadius,
231 VertexBuffer& ambientBuffer, VertexBuffer& spotBuffer);
232
Chris Craik05f3d6e2014-06-02 16:27:04 -0700233}; // namespace uirenderer
234}; // namespace android
235
236#endif // ANDROID_HWUI_PATH_CACHE_H