blob: e663402a80f3464538229ed333fd4025c046d558 [file] [log] [blame]
Chris Craikb565df12015-10-05 13:00:52 -07001/*
2 * Copyright (C) 2015 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_RECORDING_CANVAS_H
18#define ANDROID_HWUI_RECORDING_CANVAS_H
19
Chris Craikb565df12015-10-05 13:00:52 -070020#include "CanvasState.h"
21#include "DisplayList.h"
Chris Craikb565df12015-10-05 13:00:52 -070022#include "ResourceCache.h"
23#include "SkiaCanvasProxy.h"
24#include "Snapshot.h"
sergeyvec4a4b12016-10-20 18:39:04 -070025#include "hwui/Bitmap.h"
sergeyvdccca442016-03-21 15:38:21 -070026#include "hwui/Canvas.h"
Chris Craik9fded232015-11-11 16:42:34 -080027#include "utils/LinearAllocator.h"
28#include "utils/Macros.h"
Chris Craikb565df12015-10-05 13:00:52 -070029
Chris Craik0b7e8242015-10-28 16:50:44 -070030#include <SkDrawFilter.h>
31#include <SkPaint.h>
32#include <SkTLazy.h>
33
Chris Craikb565df12015-10-05 13:00:52 -070034#include <vector>
35
36namespace android {
37namespace uirenderer {
38
Chris Craike4db79d2015-12-22 16:32:23 -080039struct ClipBase;
Chris Craikd2dfd8f2015-12-16 14:27:20 -080040class DeferredLayerUpdater;
Chris Craikb565df12015-10-05 13:00:52 -070041struct RecordedOp;
42
John Reck1bcacfd2017-11-03 10:12:19 -070043class ANDROID_API RecordingCanvas : public Canvas, public CanvasStateClient {
Chris Craik161f54b2015-11-05 11:08:52 -080044 enum class DeferredBarrierType {
45 None,
46 InOrder,
47 OutOfOrder,
48 };
John Reck1bcacfd2017-11-03 10:12:19 -070049
Chris Craikb565df12015-10-05 13:00:52 -070050public:
51 RecordingCanvas(size_t width, size_t height);
52 virtual ~RecordingCanvas();
53
Stan Ilievc0e7a902016-10-13 17:07:09 -040054 virtual void resetRecording(int width, int height, RenderNode* node = nullptr) override;
Derek Sollenberger6f485562015-07-30 10:00:39 -040055 virtual WARN_UNUSED_RESULT DisplayList* finishRecording() override;
John Reck1bcacfd2017-11-03 10:12:19 -070056 // ----------------------------------------------------------------------------
57 // MISC HWUI OPERATIONS - TODO: CATEGORIZE
58 // ----------------------------------------------------------------------------
Chris Craikd6456402016-04-11 12:24:23 -070059 virtual void insertReorderBarrier(bool enableReorder) override;
Chris Craikd2dfd8f2015-12-16 14:27:20 -080060
Derek Sollenberger6f485562015-07-30 10:00:39 -040061 virtual void drawLayer(DeferredLayerUpdater* layerHandle) override;
62 virtual void drawRenderNode(RenderNode* renderNode) override;
John Reckcd1c3eb2016-04-14 10:38:54 -070063 virtual void callDrawGLFunction(Functor* functor,
John Reck1bcacfd2017-11-03 10:12:19 -070064 GlFunctorLifecycleListener* listener) override;
Chris Craike29ce6f2015-12-10 16:25:13 -080065
John Reck1bcacfd2017-11-03 10:12:19 -070066 // ----------------------------------------------------------------------------
67 // CanvasStateClient interface
68 // ----------------------------------------------------------------------------
Chris Craik6fe991e52015-10-20 09:39:42 -070069 virtual void onViewportInitialized() override;
70 virtual void onSnapshotRestored(const Snapshot& removed, const Snapshot& restored) override;
Chris Craikb565df12015-10-05 13:00:52 -070071 virtual GLuint getTargetFbo() const override { return -1; }
72
John Reck1bcacfd2017-11-03 10:12:19 -070073 // ----------------------------------------------------------------------------
74 // HWUI Canvas draw operations
75 // ----------------------------------------------------------------------------
Chris Craik268a9c02015-12-09 18:05:12 -080076
Derek Sollenberger6f485562015-07-30 10:00:39 -040077 virtual void drawRoundRect(CanvasPropertyPrimitive* left, CanvasPropertyPrimitive* top,
John Reck1bcacfd2017-11-03 10:12:19 -070078 CanvasPropertyPrimitive* right, CanvasPropertyPrimitive* bottom,
79 CanvasPropertyPrimitive* rx, CanvasPropertyPrimitive* ry,
80 CanvasPropertyPaint* paint) override;
Derek Sollenberger6f485562015-07-30 10:00:39 -040081 virtual void drawCircle(CanvasPropertyPrimitive* x, CanvasPropertyPrimitive* y,
John Reck1bcacfd2017-11-03 10:12:19 -070082 CanvasPropertyPrimitive* radius, CanvasPropertyPaint* paint) override;
Chris Craik268a9c02015-12-09 18:05:12 -080083
John Reck1bcacfd2017-11-03 10:12:19 -070084 // ----------------------------------------------------------------------------
85 // android/graphics/Canvas interface
86 // ----------------------------------------------------------------------------
Chris Craikb565df12015-10-05 13:00:52 -070087 virtual SkCanvas* asSkCanvas() override;
88
89 virtual void setBitmap(const SkBitmap& bitmap) override {
90 LOG_ALWAYS_FATAL("RecordingCanvas is not backed by a bitmap.");
91 }
92
93 virtual bool isOpaque() override { return false; }
94 virtual int width() override { return mState.getWidth(); }
95 virtual int height() override { return mState.getHeight(); }
96
John Reck1bcacfd2017-11-03 10:12:19 -070097 // ----------------------------------------------------------------------------
98 // android/graphics/Canvas state operations
99 // ----------------------------------------------------------------------------
Chris Craikb565df12015-10-05 13:00:52 -0700100 // Save (layer)
101 virtual int getSaveCount() const override { return mState.getSaveCount(); }
Florin Malitaeecff562015-12-21 10:43:01 -0500102 virtual int save(SaveFlags::Flags flags) override;
Chris Craikb565df12015-10-05 13:00:52 -0700103 virtual void restore() override;
104 virtual void restoreToCount(int saveCount) override;
105
106 virtual int saveLayer(float left, float top, float right, float bottom, const SkPaint* paint,
John Reck1bcacfd2017-11-03 10:12:19 -0700107 SaveFlags::Flags flags) override;
108 virtual int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
109 SaveFlags::Flags flags) override {
Chris Craikb565df12015-10-05 13:00:52 -0700110 SkPaint paint;
111 paint.setAlpha(alpha);
112 return saveLayer(left, top, right, bottom, &paint, flags);
113 }
114
115 // Matrix
116 virtual void getMatrix(SkMatrix* outMatrix) const override { mState.getMatrix(outMatrix); }
117 virtual void setMatrix(const SkMatrix& matrix) override { mState.setMatrix(matrix); }
118
119 virtual void concat(const SkMatrix& matrix) override { mState.concatMatrix(matrix); }
120 virtual void rotate(float degrees) override;
121 virtual void scale(float sx, float sy) override;
122 virtual void skew(float sx, float sy) override;
123 virtual void translate(float dx, float dy) override;
124
125 // Clip
126 virtual bool getClipBounds(SkRect* outRect) const override;
127 virtual bool quickRejectRect(float left, float top, float right, float bottom) const override;
128 virtual bool quickRejectPath(const SkPath& path) const override;
129
John Reck1bcacfd2017-11-03 10:12:19 -0700130 virtual bool clipRect(float left, float top, float right, float bottom, SkClipOp op) override;
Mike Reed6e49c9f2016-12-02 15:36:59 -0500131 virtual bool clipPath(const SkPath* path, SkClipOp op) override;
Chris Craikb565df12015-10-05 13:00:52 -0700132
133 // Misc
134 virtual SkDrawFilter* getDrawFilter() override { return mDrawFilter.get(); }
135 virtual void setDrawFilter(SkDrawFilter* filter) override {
136 mDrawFilter.reset(SkSafeRef(filter));
137 }
138
John Reck1bcacfd2017-11-03 10:12:19 -0700139 // ----------------------------------------------------------------------------
140 // android/graphics/Canvas draw operations
141 // ----------------------------------------------------------------------------
Mike Reed260ab722016-10-07 15:59:20 -0400142 virtual void drawColor(int color, SkBlendMode mode) override;
Chris Craikb565df12015-10-05 13:00:52 -0700143 virtual void drawPaint(const SkPaint& paint) override;
144
145 // Geometry
146 virtual void drawPoint(float x, float y, const SkPaint& paint) override {
John Reck1bcacfd2017-11-03 10:12:19 -0700147 float points[2] = {x, y};
Chris Craikb565df12015-10-05 13:00:52 -0700148 drawPoints(points, 2, paint);
149 }
Chris Craik386aa032015-12-07 17:08:25 -0800150 virtual void drawPoints(const float* points, int floatCount, const SkPaint& paint) override;
Chris Craikb565df12015-10-05 13:00:52 -0700151 virtual void drawLine(float startX, float startY, float stopX, float stopY,
John Reck1bcacfd2017-11-03 10:12:19 -0700152 const SkPaint& paint) override {
153 float points[4] = {startX, startY, stopX, stopY};
Chris Craikb565df12015-10-05 13:00:52 -0700154 drawLines(points, 4, paint);
155 }
Chris Craik386aa032015-12-07 17:08:25 -0800156 virtual void drawLines(const float* points, int floatCount, const SkPaint& paint) override;
John Reck1bcacfd2017-11-03 10:12:19 -0700157 virtual void drawRect(float left, float top, float right, float bottom,
158 const SkPaint& paint) override;
Chris Craikb565df12015-10-05 13:00:52 -0700159 virtual void drawRegion(const SkRegion& region, const SkPaint& paint) override;
John Reck1bcacfd2017-11-03 10:12:19 -0700160 virtual void drawRoundRect(float left, float top, float right, float bottom, float rx, float ry,
161 const SkPaint& paint) override;
Chris Craikb565df12015-10-05 13:00:52 -0700162 virtual void drawCircle(float x, float y, float radius, const SkPaint& paint) override;
John Reck1bcacfd2017-11-03 10:12:19 -0700163 virtual void drawOval(float left, float top, float right, float bottom,
164 const SkPaint& paint) override;
165 virtual void drawArc(float left, float top, float right, float bottom, float startAngle,
166 float sweepAngle, bool useCenter, const SkPaint& paint) override;
Chris Craikb565df12015-10-05 13:00:52 -0700167 virtual void drawPath(const SkPath& path, const SkPaint& paint) override;
John Reck1bcacfd2017-11-03 10:12:19 -0700168 virtual void drawVertices(const SkVertices*, SkBlendMode, const SkPaint& paint)
169 override { /* RecordingCanvas does not support drawVertices(); ignore */
170 }
Chris Craikb565df12015-10-05 13:00:52 -0700171
Doris Liu766431a2016-02-04 22:17:11 +0000172 virtual void drawVectorDrawable(VectorDrawableRoot* tree) override;
173
Chris Craikb565df12015-10-05 13:00:52 -0700174 // Bitmap-based
sergeyvaed7f582016-10-14 16:30:21 -0700175 virtual void drawBitmap(Bitmap& bitmap, float left, float top, const SkPaint* paint) override;
sergeyvfc9999502016-10-17 13:07:38 -0700176 virtual void drawBitmap(Bitmap& bitmap, const SkMatrix& matrix, const SkPaint* paint) override;
John Reck1bcacfd2017-11-03 10:12:19 -0700177 virtual void drawBitmap(Bitmap& bitmap, float srcLeft, float srcTop, float srcRight,
178 float srcBottom, float dstLeft, float dstTop, float dstRight,
179 float dstBottom, const SkPaint* paint) override;
sergeyv5fd2a1c2016-10-20 15:04:28 -0700180 virtual void drawBitmapMesh(Bitmap& bitmap, int meshWidth, int meshHeight,
John Reck1bcacfd2017-11-03 10:12:19 -0700181 const float* vertices, const int* colors,
182 const SkPaint* paint) override;
183 virtual void drawNinePatch(Bitmap& bitmap, const android::Res_png_9patch& chunk, float dstLeft,
184 float dstTop, float dstRight, float dstBottom,
185 const SkPaint* paint) override;
Derek Sollenberger2d142132018-01-22 10:25:26 -0500186 virtual double drawAnimatedImage(AnimatedImageDrawable*) override;
Chris Craikb565df12015-10-05 13:00:52 -0700187
188 // Text
Chris Craikb565df12015-10-05 13:00:52 -0700189 virtual bool drawTextAbsolutePos() const override { return false; }
190
Derek Sollenberger79abbf22016-03-24 11:07:19 -0400191protected:
Stan Iliev0b58d992017-03-30 18:22:27 -0400192 virtual void drawGlyphs(ReadGlyphFunc glyphFunc, int count, const SkPaint& paint, float x,
John Reck1bcacfd2017-11-03 10:12:19 -0700193 float y, float boundsLeft, float boundsTop, float boundsRight,
194 float boundsBottom, float totalAdvance) override;
Yuqian Liafc221492016-07-18 13:07:42 -0400195 virtual void drawLayoutOnPath(const minikin::Layout& layout, float hOffset, float vOffset,
John Reck1bcacfd2017-11-03 10:12:19 -0700196 const SkPaint& paint, const SkPath& path, size_t start,
197 size_t end) override;
Derek Sollenberger79abbf22016-03-24 11:07:19 -0400198
Chris Craikb565df12015-10-05 13:00:52 -0700199private:
Chris Craike4db79d2015-12-22 16:32:23 -0800200 const ClipBase* getRecordedClip() {
201 return mState.writableSnapshot()->mutateClipArea().serializeClip(alloc());
202 }
Chris Craikb565df12015-10-05 13:00:52 -0700203
sergeyvec4a4b12016-10-20 18:39:04 -0700204 void drawBitmap(Bitmap& bitmap, const SkPaint* paint);
Chris Craikb565df12015-10-05 13:00:52 -0700205 void drawSimpleRects(const float* rects, int vertexCount, const SkPaint* paint);
206
Chris Craik3c53ec52016-08-08 15:15:57 -0700207 int addOp(RecordedOp* op);
John Reck1bcacfd2017-11-03 10:12:19 -0700208 // ----------------------------------------------------------------------------
209 // lazy object copy
210 // ----------------------------------------------------------------------------
Chris Craik003cc3d2015-10-16 10:24:55 -0700211 LinearAllocator& alloc() { return mDisplayList->allocator; }
Chris Craikb565df12015-10-05 13:00:52 -0700212
213 void refBitmapsInShader(const SkShader* shader);
214
John Reck1bcacfd2017-11-03 10:12:19 -0700215 template <class T>
Chris Craikb565df12015-10-05 13:00:52 -0700216 inline const T* refBuffer(const T* srcBuffer, int32_t count) {
217 if (!srcBuffer) return nullptr;
218
John Reck1bcacfd2017-11-03 10:12:19 -0700219 T* dstBuffer = (T*)mDisplayList->allocator.alloc<T>(count * sizeof(T));
Chris Craikb565df12015-10-05 13:00:52 -0700220 memcpy(dstBuffer, srcBuffer, count * sizeof(T));
221 return dstBuffer;
222 }
223
Chris Craikb565df12015-10-05 13:00:52 -0700224 inline const SkPath* refPath(const SkPath* path) {
225 if (!path) return nullptr;
226
227 // The points/verbs within the path are refcounted so this copy operation
228 // is inexpensive and maintains the generationID of the original path.
229 const SkPath* cachedPath = new SkPath(*path);
Chris Craik003cc3d2015-10-16 10:24:55 -0700230 mDisplayList->pathResources.push_back(cachedPath);
Chris Craikb565df12015-10-05 13:00:52 -0700231 return cachedPath;
232 }
233
Chris Craika1717272015-11-19 13:02:43 -0800234 /**
Chris Craik42a54072015-11-24 11:41:54 -0800235 * Returns a RenderThread-safe, const copy of the SkPaint parameter passed in
236 * (with deduping based on paint hash / equality check)
Chris Craika1717272015-11-19 13:02:43 -0800237 */
Chris Craikb565df12015-10-05 13:00:52 -0700238 inline const SkPaint* refPaint(const SkPaint* paint) {
239 if (!paint) return nullptr;
240
241 // If there is a draw filter apply it here and store the modified paint
242 // so that we don't need to modify the paint every time we access it.
243 SkTLazy<SkPaint> filteredPaint;
244 if (mDrawFilter.get()) {
245 filteredPaint.set(*paint);
246 mDrawFilter->filter(filteredPaint.get(), SkDrawFilter::kPaint_Type);
247 paint = filteredPaint.get();
248 }
249
250 // compute the hash key for the paint and check the cache.
251 const uint32_t key = paint->getHash();
252 const SkPaint* cachedPaint = mPaintMap.valueFor(key);
253 // In the unlikely event that 2 unique paints have the same hash we do a
254 // object equality check to ensure we don't erroneously dedup them.
255 if (cachedPaint == nullptr || *cachedPaint != *paint) {
Chris Craik42a54072015-11-24 11:41:54 -0800256 cachedPaint = new SkPaint(*paint);
257 mDisplayList->paints.emplace_back(cachedPaint);
Chris Craikb565df12015-10-05 13:00:52 -0700258 // replaceValueFor() performs an add if the entry doesn't exist
259 mPaintMap.replaceValueFor(key, cachedPaint);
260 refBitmapsInShader(cachedPaint->getShader());
261 }
262
263 return cachedPaint;
264 }
265
266 inline const SkRegion* refRegion(const SkRegion* region) {
267 if (!region) {
268 return region;
269 }
270
271 const SkRegion* cachedRegion = mRegionMap.valueFor(region);
272 // TODO: Add generation ID to SkRegion
273 if (cachedRegion == nullptr) {
274 std::unique_ptr<const SkRegion> copy(new SkRegion(*region));
275 cachedRegion = copy.get();
Chris Craik003cc3d2015-10-16 10:24:55 -0700276 mDisplayList->regions.push_back(std::move(copy));
Chris Craikb565df12015-10-05 13:00:52 -0700277
278 // replaceValueFor() performs an add if the entry doesn't exist
279 mRegionMap.replaceValueFor(region, cachedRegion);
280 }
281
282 return cachedRegion;
283 }
284
sergeyvec4a4b12016-10-20 18:39:04 -0700285 inline Bitmap* refBitmap(Bitmap& bitmap) {
Chris Craikb565df12015-10-05 13:00:52 -0700286 // Note that this assumes the bitmap is immutable. There are cases this won't handle
287 // correctly, such as creating the bitmap from scratch, drawing with it, changing its
288 // contents, and drawing again. The only fix would be to always copy it the first time,
289 // which doesn't seem worth the extra cycles for this unlikely case.
sergeyvec4a4b12016-10-20 18:39:04 -0700290
291 // this is required because sk_sp's ctor adopts the pointer,
292 // but does not increment the refcount,
293 bitmap.ref();
294 mDisplayList->bitmapResources.emplace_back(&bitmap);
295 return &bitmap;
Chris Craikb565df12015-10-05 13:00:52 -0700296 }
297
298 inline const Res_png_9patch* refPatch(const Res_png_9patch* patch) {
Chris Craik003cc3d2015-10-16 10:24:55 -0700299 mDisplayList->patchResources.push_back(patch);
Chris Craikb565df12015-10-05 13:00:52 -0700300 mResourceCache.incrementRefcount(patch);
301 return patch;
302 }
303
304 DefaultKeyedVector<uint32_t, const SkPaint*> mPaintMap;
305 DefaultKeyedVector<const SkPath*, const SkPath*> mPathMap;
306 DefaultKeyedVector<const SkRegion*, const SkRegion*> mRegionMap;
307
308 CanvasState mState;
309 std::unique_ptr<SkiaCanvasProxy> mSkiaCanvasProxy;
310 ResourceCache& mResourceCache;
Chris Craik161f54b2015-11-05 11:08:52 -0800311 DeferredBarrierType mDeferredBarrierType = DeferredBarrierType::None;
Chris Craikd6456402016-04-11 12:24:23 -0700312 const ClipBase* mDeferredBarrierClip = nullptr;
Chris Craik003cc3d2015-10-16 10:24:55 -0700313 DisplayList* mDisplayList = nullptr;
Ben Wagner18bd8852016-10-24 14:50:10 -0400314 sk_sp<SkDrawFilter> mDrawFilter;
John Reck1bcacfd2017-11-03 10:12:19 -0700315}; // class RecordingCanvas
Chris Craikb565df12015-10-05 13:00:52 -0700316
John Reck1bcacfd2017-11-03 10:12:19 -0700317}; // namespace uirenderer
318}; // namespace android
Chris Craikb565df12015-10-05 13:00:52 -0700319
John Reck1bcacfd2017-11-03 10:12:19 -0700320#endif // ANDROID_HWUI_RECORDING_CANVAS_H