blob: a0f0ed4653e00eaa2da9b1ac75b8c52acb152893 [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
Chris Craik5e00c7c2016-07-06 16:10:09 -070017#pragma once
Chris Craik05f3d6e2014-06-02 16:27:04 -070018
Chris Craik05f3d6e2014-06-02 16:27:04 -070019#include "Debug.h"
John Reck82f5e0c2015-10-22 17:07:45 -070020#include "Matrix.h"
21#include "Rect.h"
22#include "Vector.h"
Chris Craikd8165e82016-02-03 15:52:25 -080023#include "VertexBuffer.h"
John Reck82f5e0c2015-10-22 17:07:45 -070024#include "thread/TaskProcessor.h"
Chris Craik05f3d6e2014-06-02 16:27:04 -070025#include "utils/Macros.h"
26#include "utils/Pair.h"
Chris Craik05f3d6e2014-06-02 16:27:04 -070027
John Reck82f5e0c2015-10-22 17:07:45 -070028#include <SkPaint.h>
Chris Craik6e068c012016-01-15 16:15:30 -080029#include <SkPath.h>
John Reck82f5e0c2015-10-22 17:07:45 -070030
31#include <utils/LruCache.h>
32#include <utils/Mutex.h>
33#include <utils/StrongPointer.h>
34
Chris Craik05f3d6e2014-06-02 16:27:04 -070035class SkBitmap;
36class SkCanvas;
Chris Craik05f3d6e2014-06-02 16:27:04 -070037struct SkRect;
38
39namespace android {
40namespace uirenderer {
41
42class Caches;
Tom Hudson2dc236b2014-10-15 15:46:42 -040043class VertexBuffer;
Chris Craik05f3d6e2014-06-02 16:27:04 -070044
45///////////////////////////////////////////////////////////////////////////////
46// Classes
47///////////////////////////////////////////////////////////////////////////////
48
49class TessellationCache {
50public:
51 typedef Pair<VertexBuffer*, VertexBuffer*> vertexBuffer_pair_t;
52
53 struct Description {
sergeyv7224e2b2016-04-07 18:06:53 -070054 HASHABLE_TYPE(Description);
55 enum class Type {
56 None,
57 RoundRect,
Chris Craik05f3d6e2014-06-02 16:27:04 -070058 };
59
60 Type type;
Chris Craik6ac174b2014-06-17 13:47:05 -070061 float scaleX;
62 float scaleY;
Chris Craiked4ef0b2014-06-12 13:27:30 -070063 bool aa;
Chris Craik05f3d6e2014-06-02 16:27:04 -070064 SkPaint::Cap cap;
65 SkPaint::Style style;
66 float strokeWidth;
67 union Shape {
68 struct RoundRect {
Chris Craik6ac174b2014-06-17 13:47:05 -070069 float width;
70 float height;
71 float rx;
72 float ry;
Chris Craik05f3d6e2014-06-02 16:27:04 -070073 } roundRect;
74 } shape;
75
76 Description();
Chris Craik6ac174b2014-06-17 13:47:05 -070077 Description(Type type, const Matrix4& transform, const SkPaint& paint);
Chris Craik6ac174b2014-06-17 13:47:05 -070078 void setupMatrixAndPaint(Matrix4* matrix, SkPaint* paint) const;
Chris Craik05f3d6e2014-06-02 16:27:04 -070079 };
80
81 struct ShadowDescription {
sergeyv7224e2b2016-04-07 18:06:53 -070082 HASHABLE_TYPE(ShadowDescription);
83 const SkPath* nodeKey;
Chris Craik05f3d6e2014-06-02 16:27:04 -070084 float matrixData[16];
85
86 ShadowDescription();
sergeyv7224e2b2016-04-07 18:06:53 -070087 ShadowDescription(const SkPath* nodeKey, const Matrix4* drawTransform);
Chris Craik05f3d6e2014-06-02 16:27:04 -070088 };
89
Chris Craikd8165e82016-02-03 15:52:25 -080090 class ShadowTask : public Task<vertexBuffer_pair_t> {
Chris Craik6e068c012016-01-15 16:15:30 -080091 public:
92 ShadowTask(const Matrix4* drawTransform, const Rect& localClip, bool opaque,
John Reck1bcacfd2017-11-03 10:12:19 -070093 const SkPath* casterPerimeter, const Matrix4* transformXY,
94 const Matrix4* transformZ, const Vector3& lightCenter, float lightRadius)
95 : drawTransform(*drawTransform)
96 , localClip(localClip)
97 , opaque(opaque)
98 , casterPerimeter(*casterPerimeter)
99 , transformXY(*transformXY)
100 , transformZ(*transformZ)
101 , lightCenter(lightCenter)
102 , lightRadius(lightRadius) {}
Chris Craik6e068c012016-01-15 16:15:30 -0800103
Chris Craik6e068c012016-01-15 16:15:30 -0800104 /* Note - we deep copy all task parameters, because *even though* pointers into Allocator
105 * controlled objects (like the SkPath and Matrix4s) should be safe for the entire frame,
106 * certain Allocators are destroyed before trim() is called to flush incomplete tasks.
107 *
Chris Craikd8165e82016-02-03 15:52:25 -0800108 * These deep copies could be avoided, long term, by canceling or flushing outstanding
Chris Craik6e068c012016-01-15 16:15:30 -0800109 * tasks before tearing down single-frame LinearAllocators.
110 */
111 const Matrix4 drawTransform;
112 const Rect localClip;
113 bool opaque;
114 const SkPath casterPerimeter;
115 const Matrix4 transformXY;
116 const Matrix4 transformZ;
117 const Vector3 lightCenter;
118 const float lightRadius;
Chris Craikd8165e82016-02-03 15:52:25 -0800119 VertexBuffer ambientBuffer;
120 VertexBuffer spotBuffer;
Chris Craik6e068c012016-01-15 16:15:30 -0800121 };
122
Chris Craik05f3d6e2014-06-02 16:27:04 -0700123 TessellationCache();
124 ~TessellationCache();
125
126 /**
127 * Clears the cache. This causes all TessellationBuffers to be deleted.
128 */
129 void clear();
Chris Craik05f3d6e2014-06-02 16:27:04 -0700130 /**
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 /**
140 * Trims the contents of the cache, removing items until it's under its
141 * specified limit.
142 *
143 * Trimming is used for caches that support pre-caching from a worker
144 * thread. During pre-caching the maximum limit of the cache can be
145 * exceeded for the duration of the frame. It is therefore required to
146 * trim the cache at the end of the frame to keep the total amount of
147 * memory used under control.
148 *
149 * Also removes transient Shadow VertexBuffers, which aren't cached between frames.
150 */
151 void trim();
152
153 // TODO: precache/get for Oval, Lines, Points, etc.
154
John Reck1bcacfd2017-11-03 10:12:19 -0700155 void precacheRoundRect(const Matrix4& transform, const SkPaint& paint, float width,
156 float height, float rx, float ry) {
Chris Craik6ac174b2014-06-17 13:47:05 -0700157 getRoundRectBuffer(transform, paint, width, height, rx, ry);
Chris Craik05f3d6e2014-06-02 16:27:04 -0700158 }
John Reck1bcacfd2017-11-03 10:12:19 -0700159 const VertexBuffer* getRoundRect(const Matrix4& transform, const SkPaint& paint, float width,
160 float height, float rx, float ry);
Chris Craik05f3d6e2014-06-02 16:27:04 -0700161
John Reck1bcacfd2017-11-03 10:12:19 -0700162 sp<ShadowTask> getShadowTask(const Matrix4* drawTransform, const Rect& localClip, bool opaque,
163 const SkPath* casterPerimeter, const Matrix4* transformXY,
164 const Matrix4* transformZ, const Vector3& lightCenter,
165 float lightRadius);
Chris Craik6e068c012016-01-15 16:15:30 -0800166
Chris Craik05f3d6e2014-06-02 16:27:04 -0700167private:
168 class Buffer;
169 class TessellationTask;
170 class TessellationProcessor;
171
Chris Craik6ac174b2014-06-17 13:47:05 -0700172 typedef VertexBuffer* (*Tessellator)(const Description&);
Chris Craik05f3d6e2014-06-02 16:27:04 -0700173
John Reck1bcacfd2017-11-03 10:12:19 -0700174 void precacheShadows(const Matrix4* drawTransform, const Rect& localClip, bool opaque,
175 const SkPath* casterPerimeter, const Matrix4* transformXY,
176 const Matrix4* transformZ, const Vector3& lightCenter, float lightRadius);
Chris Craik5e00c7c2016-07-06 16:10:09 -0700177
John Reck1bcacfd2017-11-03 10:12:19 -0700178 Buffer* getRectBuffer(const Matrix4& transform, const SkPaint& paint, float width,
179 float height);
180 Buffer* getRoundRectBuffer(const Matrix4& transform, const SkPaint& paint, float width,
181 float height, float rx, float ry);
Chris Craik05f3d6e2014-06-02 16:27:04 -0700182
Chris Craik6ac174b2014-06-17 13:47:05 -0700183 Buffer* getOrCreateBuffer(const Description& entry, Tessellator tessellator);
Chris Craik05f3d6e2014-06-02 16:27:04 -0700184
Chris Craik48a8f432016-02-05 15:59:29 -0800185 const uint32_t mMaxSize;
Chris Craik05f3d6e2014-06-02 16:27:04 -0700186
187 bool mDebugEnabled;
188
189 mutable Mutex mLock;
190
191 ///////////////////////////////////////////////////////////////////////////////
192 // General tessellation caching
193 ///////////////////////////////////////////////////////////////////////////////
194 sp<TaskProcessor<VertexBuffer*> > mProcessor;
195 LruCache<Description, Buffer*> mCache;
196 class BufferRemovedListener : public OnEntryRemoved<Description, Buffer*> {
Chris Craike84a2082014-12-22 14:28:49 -0800197 void operator()(Description& description, Buffer*& buffer) override;
Chris Craik05f3d6e2014-06-02 16:27:04 -0700198 };
199 BufferRemovedListener mBufferRemovedListener;
200
201 ///////////////////////////////////////////////////////////////////////////////
202 // Shadow tessellation caching
203 ///////////////////////////////////////////////////////////////////////////////
Chris Craikd8165e82016-02-03 15:52:25 -0800204 sp<TaskProcessor<vertexBuffer_pair_t> > mShadowProcessor;
Chris Craik05f3d6e2014-06-02 16:27:04 -0700205
206 // holds a pointer, and implicit strong ref to each shadow task of the frame
Chris Craikd8165e82016-02-03 15:52:25 -0800207 LruCache<ShadowDescription, Task<vertexBuffer_pair_t>*> mShadowCache;
John Reck1bcacfd2017-11-03 10:12:19 -0700208 class BufferPairRemovedListener
209 : public OnEntryRemoved<ShadowDescription, Task<vertexBuffer_pair_t>*> {
210 void operator()(ShadowDescription& description,
211 Task<vertexBuffer_pair_t>*& bufferPairTask) override {
Chris Craike84a2082014-12-22 14:28:49 -0800212 bufferPairTask->decStrong(nullptr);
Chris Craik05f3d6e2014-06-02 16:27:04 -0700213 }
214 };
215 BufferPairRemovedListener mBufferPairRemovedListener;
216
John Reck1bcacfd2017-11-03 10:12:19 -0700217}; // class TessellationCache
Chris Craik05f3d6e2014-06-02 16:27:04 -0700218
John Reck1bcacfd2017-11-03 10:12:19 -0700219void tessellateShadows(const Matrix4* drawTransform, const Rect* localClip, bool isCasterOpaque,
220 const SkPath* casterPerimeter, const Matrix4* casterTransformXY,
221 const Matrix4* casterTransformZ, const Vector3& lightCenter,
222 float lightRadius, VertexBuffer& ambientBuffer, VertexBuffer& spotBuffer);
John Reck82f5e0c2015-10-22 17:07:45 -0700223
John Reck1bcacfd2017-11-03 10:12:19 -0700224}; // namespace uirenderer
225}; // namespace android