blob: 3a76ca1137a579a438b89f5d8dd84f47aabcab6d [file] [log] [blame]
John Reck8f45d4a2018-08-15 10:17:12 -07001/*
2 * Copyright (C) 2018 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#pragma once
18
19#include "CanvasTransform.h"
John Reckf3c724f2018-09-20 13:00:04 -070020#include "hwui/Bitmap.h"
John Reck8f45d4a2018-08-15 10:17:12 -070021#include "hwui/Canvas.h"
22#include "utils/Macros.h"
23#include "utils/TypeLogic.h"
24
25#include "SkCanvas.h"
26#include "SkCanvasVirtualEnforcer.h"
27#include "SkDrawable.h"
28#include "SkNoDrawCanvas.h"
29#include "SkPaint.h"
30#include "SkPath.h"
31#include "SkRect.h"
32#include "SkTDArray.h"
33#include "SkTemplates.h"
34
35#include <vector>
36
37namespace android {
38namespace uirenderer {
39
40enum class DisplayListOpType : uint8_t {
41#define X(T) T,
42#include "DisplayListOps.in"
43#undef X
44};
45
46struct DisplayListOp {
47 const uint8_t type : 8;
48 const uint32_t skip : 24;
49};
50
51static_assert(sizeof(DisplayListOp) == 4);
52
53class RecordingCanvas;
54
55class DisplayListData final {
56public:
John Reckf3c724f2018-09-20 13:00:04 -070057 DisplayListData() : mHasText(false) {}
John Reck8f45d4a2018-08-15 10:17:12 -070058 ~DisplayListData();
59
60 void draw(SkCanvas* canvas) const;
61
62 void reset();
63 bool empty() const { return fUsed == 0; }
64
65 void applyColorTransform(ColorTransform transform);
66
John Reckf3c724f2018-09-20 13:00:04 -070067 bool hasText() const { return mHasText; }
John Reck470a9192018-12-17 10:55:54 -080068 size_t usedSize() const { return fUsed; }
John Reckf3c724f2018-09-20 13:00:04 -070069
John Reck8f45d4a2018-08-15 10:17:12 -070070private:
71 friend class RecordingCanvas;
72
73 void flush();
74
75 void save();
76 void saveLayer(const SkRect*, const SkPaint*, const SkImageFilter*, const SkImage*,
77 const SkMatrix*, SkCanvas::SaveLayerFlags);
Derek Sollenberger24fc9012018-12-07 14:12:12 -050078 void saveBehind(const SkRect*);
John Reck8f45d4a2018-08-15 10:17:12 -070079 void restore();
80
81 void concat(const SkMatrix&);
82 void setMatrix(const SkMatrix&);
83 void translate(SkScalar, SkScalar);
84 void translateZ(SkScalar);
85
86 void clipPath(const SkPath&, SkClipOp, bool aa);
87 void clipRect(const SkRect&, SkClipOp, bool aa);
88 void clipRRect(const SkRRect&, SkClipOp, bool aa);
89 void clipRegion(const SkRegion&, SkClipOp);
90
91 void drawPaint(const SkPaint&);
92 void drawPath(const SkPath&, const SkPaint&);
93 void drawRect(const SkRect&, const SkPaint&);
94 void drawRegion(const SkRegion&, const SkPaint&);
95 void drawOval(const SkRect&, const SkPaint&);
96 void drawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&);
97 void drawRRect(const SkRRect&, const SkPaint&);
98 void drawDRRect(const SkRRect&, const SkRRect&, const SkPaint&);
99
100 void drawAnnotation(const SkRect&, const char*, SkData*);
101 void drawDrawable(SkDrawable*, const SkMatrix*);
102 void drawPicture(const SkPicture*, const SkMatrix*, const SkPaint*);
103
John Reck8f45d4a2018-08-15 10:17:12 -0700104 void drawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&);
105
John Reckf3c724f2018-09-20 13:00:04 -0700106 void drawImage(sk_sp<const SkImage>, SkScalar, SkScalar, const SkPaint*, BitmapPalette palette);
John Reck8f45d4a2018-08-15 10:17:12 -0700107 void drawImageNine(sk_sp<const SkImage>, const SkIRect&, const SkRect&, const SkPaint*);
108 void drawImageRect(sk_sp<const SkImage>, const SkRect*, const SkRect&, const SkPaint*,
John Reckf3c724f2018-09-20 13:00:04 -0700109 SkCanvas::SrcRectConstraint, BitmapPalette palette);
John Reck8f45d4a2018-08-15 10:17:12 -0700110 void drawImageLattice(sk_sp<const SkImage>, const SkCanvas::Lattice&, const SkRect&,
John Reck3b4510cd2018-09-27 17:39:45 -0700111 const SkPaint*, BitmapPalette);
John Reck8f45d4a2018-08-15 10:17:12 -0700112
113 void drawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4], SkBlendMode,
114 const SkPaint&);
115 void drawPoints(SkCanvas::PointMode, size_t, const SkPoint[], const SkPaint&);
116 void drawVertices(const SkVertices*, const SkVertices::Bone bones[], int boneCount, SkBlendMode,
117 const SkPaint&);
118 void drawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int,
119 SkBlendMode, const SkRect*, const SkPaint*);
120 void drawShadowRec(const SkPath&, const SkDrawShadowRec&);
John Reck08ee8152018-09-20 16:27:46 -0700121 void drawVectorDrawable(VectorDrawableRoot* tree);
John Reck8f45d4a2018-08-15 10:17:12 -0700122
123 template <typename T, typename... Args>
124 void* push(size_t, Args&&...);
125
126 template <typename Fn, typename... Args>
127 void map(const Fn[], Args...) const;
128
129 SkAutoTMalloc<uint8_t> fBytes;
130 size_t fUsed = 0;
131 size_t fReserved = 0;
John Reckf3c724f2018-09-20 13:00:04 -0700132
133 bool mHasText : 1;
John Reck8f45d4a2018-08-15 10:17:12 -0700134};
135
136class RecordingCanvas final : public SkCanvasVirtualEnforcer<SkNoDrawCanvas> {
137public:
138 RecordingCanvas();
139 void reset(DisplayListData*, const SkIRect& bounds);
140
141 sk_sp<SkSurface> onNewSurface(const SkImageInfo&, const SkSurfaceProps&) override;
142
143 void willSave() override;
144 SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
145 void willRestore() override;
Derek Sollenberger24fc9012018-12-07 14:12:12 -0500146 bool onDoSaveBehind(const SkRect*) override;
John Reck8f45d4a2018-08-15 10:17:12 -0700147
148 void onFlush() override;
149
150 void didConcat(const SkMatrix&) override;
151 void didSetMatrix(const SkMatrix&) override;
152 void didTranslate(SkScalar, SkScalar) override;
153
154 void onClipRect(const SkRect&, SkClipOp, ClipEdgeStyle) override;
155 void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override;
156 void onClipPath(const SkPath&, SkClipOp, ClipEdgeStyle) override;
157 void onClipRegion(const SkRegion&, SkClipOp) override;
158
159 void onDrawPaint(const SkPaint&) override;
160 void onDrawPath(const SkPath&, const SkPaint&) override;
161 void onDrawRect(const SkRect&, const SkPaint&) override;
162 void onDrawRegion(const SkRegion&, const SkPaint&) override;
163 void onDrawOval(const SkRect&, const SkPaint&) override;
164 void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override;
165 void onDrawRRect(const SkRRect&, const SkPaint&) override;
166 void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
167
168 void onDrawDrawable(SkDrawable*, const SkMatrix*) override;
169 void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override;
170 void onDrawAnnotation(const SkRect&, const char[], SkData*) override;
171
John Reck8f45d4a2018-08-15 10:17:12 -0700172 void onDrawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&) override;
173
174 void onDrawBitmap(const SkBitmap&, SkScalar, SkScalar, const SkPaint*) override;
175 void onDrawBitmapLattice(const SkBitmap&, const Lattice&, const SkRect&,
176 const SkPaint*) override;
177 void onDrawBitmapNine(const SkBitmap&, const SkIRect&, const SkRect&, const SkPaint*) override;
178 void onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*,
179 SrcRectConstraint) override;
180
John Reck3b4510cd2018-09-27 17:39:45 -0700181 void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top, const SkPaint* paint,
182 BitmapPalette pallete);
John Reckf3c724f2018-09-20 13:00:04 -0700183
184 void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
185 const SkPaint* paint, SrcRectConstraint constraint, BitmapPalette palette);
John Reck3b4510cd2018-09-27 17:39:45 -0700186 void drawImageLattice(const sk_sp<SkImage>& image, const Lattice& lattice, const SkRect& dst,
187 const SkPaint* paint, BitmapPalette palette);
John Reckf3c724f2018-09-20 13:00:04 -0700188
John Reck8f45d4a2018-08-15 10:17:12 -0700189 void onDrawImage(const SkImage*, SkScalar, SkScalar, const SkPaint*) override;
190 void onDrawImageLattice(const SkImage*, const Lattice&, const SkRect&, const SkPaint*) override;
191 void onDrawImageNine(const SkImage*, const SkIRect&, const SkRect&, const SkPaint*) override;
192 void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*,
193 SrcRectConstraint) override;
194
195 void onDrawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4], SkBlendMode,
196 const SkPaint&) override;
197 void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override;
198 void onDrawVerticesObject(const SkVertices*, const SkVertices::Bone bones[], int boneCount,
199 SkBlendMode, const SkPaint&) override;
200 void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int,
201 SkBlendMode, const SkRect*, const SkPaint*) override;
202 void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;
203
John Reck08ee8152018-09-20 16:27:46 -0700204 void drawVectorDrawable(VectorDrawableRoot* tree);
205
Stan Ilievf09ee582018-11-06 17:35:50 -0500206 /**
207 * If "isClipMayBeComplex" returns false, it is guaranteed the current clip is a rectangle.
208 * If the return value is true, then clip may or may not be complex (there is no guarantee).
209 */
210 inline bool isClipMayBeComplex() { return mClipMayBeComplex; }
211
John Reck8f45d4a2018-08-15 10:17:12 -0700212private:
213 typedef SkCanvasVirtualEnforcer<SkNoDrawCanvas> INHERITED;
214
Stan Ilievf09ee582018-11-06 17:35:50 -0500215 inline void setClipMayBeComplex() {
216 if (!mClipMayBeComplex) {
217 mComplexSaveCount = mSaveCount;
218 mClipMayBeComplex = true;
219 }
220 }
221
John Reck8f45d4a2018-08-15 10:17:12 -0700222 DisplayListData* fDL;
Stan Ilievf09ee582018-11-06 17:35:50 -0500223
224 /**
225 * mClipMayBeComplex tracks if the current clip is a rectangle. This flag is used to promote
226 * FunctorDrawable to a layer, if it is clipped by a non-rect.
227 */
228 bool mClipMayBeComplex = false;
229
230 /**
231 * mSaveCount is the current level of our save tree.
232 */
233 int mSaveCount = 0;
234
235 /**
236 * mComplexSaveCount is the first save level, which has a complex clip. Every level below
237 * mComplexSaveCount is assumed to have a complex clip and every level above mComplexSaveCount
238 * is guaranteed to not be complex.
239 */
240 int mComplexSaveCount = 0;
John Reck8f45d4a2018-08-15 10:17:12 -0700241};
242
Chris Blume7b8a8082018-11-30 15:51:58 -0800243} // namespace uirenderer
244} // namespace android