1 /*
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"
20 #include "hwui/Bitmap.h"
21 #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 "SkTemplates.h"
33 
34 #include <vector>
35 
36 namespace android {
37 namespace uirenderer {
38 
39 namespace skiapipeline {
40 class FunctorDrawable;
41 }
42 
43 enum class DisplayListOpType : uint8_t {
44 #define X(T) T,
45 #include "DisplayListOps.in"
46 #undef X
47 };
48 
49 struct DisplayListOp {
50     const uint8_t type : 8;
51     const uint32_t skip : 24;
52 };
53 
54 static_assert(sizeof(DisplayListOp) == 4);
55 
56 class RecordingCanvas;
57 
58 class DisplayListData final {
59 public:
DisplayListData()60     DisplayListData() : mHasText(false) {}
61     ~DisplayListData();
62 
63     void draw(SkCanvas* canvas) const;
64 
65     void reset();
empty()66     bool empty() const { return fUsed == 0; }
67 
68     void applyColorTransform(ColorTransform transform);
69 
hasText()70     bool hasText() const { return mHasText; }
usedSize()71     size_t usedSize() const { return fUsed; }
allocatedSize()72     size_t allocatedSize() const { return fReserved; }
73 
74 private:
75     friend class RecordingCanvas;
76 
77     void flush();
78 
79     void save();
80     void saveLayer(const SkRect*, const SkPaint*, const SkImageFilter*, const SkImage*,
81                    const SkMatrix*, SkCanvas::SaveLayerFlags);
82     void saveBehind(const SkRect*);
83     void restore();
84 
85     void concat44(const SkScalar colMajor[16]);
86     void concat(const SkMatrix&);
87     void setMatrix(const SkMatrix&);
88     void scale(SkScalar, SkScalar);
89     void translate(SkScalar, SkScalar);
90     void translateZ(SkScalar);
91 
92     void clipPath(const SkPath&, SkClipOp, bool aa);
93     void clipRect(const SkRect&, SkClipOp, bool aa);
94     void clipRRect(const SkRRect&, SkClipOp, bool aa);
95     void clipRegion(const SkRegion&, SkClipOp);
96 
97     void drawPaint(const SkPaint&);
98     void drawBehind(const SkPaint&);
99     void drawPath(const SkPath&, const SkPaint&);
100     void drawRect(const SkRect&, const SkPaint&);
101     void drawRegion(const SkRegion&, const SkPaint&);
102     void drawOval(const SkRect&, const SkPaint&);
103     void drawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&);
104     void drawRRect(const SkRRect&, const SkPaint&);
105     void drawDRRect(const SkRRect&, const SkRRect&, const SkPaint&);
106 
107     void drawAnnotation(const SkRect&, const char*, SkData*);
108     void drawDrawable(SkDrawable*, const SkMatrix*);
109     void drawPicture(const SkPicture*, const SkMatrix*, const SkPaint*);
110 
111     void drawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&);
112 
113     void drawImage(sk_sp<const SkImage>, SkScalar, SkScalar, const SkPaint*, BitmapPalette palette);
114     void drawImageNine(sk_sp<const SkImage>, const SkIRect&, const SkRect&, const SkPaint*);
115     void drawImageRect(sk_sp<const SkImage>, const SkRect*, const SkRect&, const SkPaint*,
116                        SkCanvas::SrcRectConstraint, BitmapPalette palette);
117     void drawImageLattice(sk_sp<const SkImage>, const SkCanvas::Lattice&, const SkRect&,
118                           const SkPaint*, BitmapPalette);
119 
120     void drawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4], SkBlendMode,
121                    const SkPaint&);
122     void drawPoints(SkCanvas::PointMode, size_t, const SkPoint[], const SkPaint&);
123     void drawVertices(const SkVertices*, const SkVertices::Bone bones[], int boneCount, SkBlendMode,
124                       const SkPaint&);
125     void drawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int,
126                    SkBlendMode, const SkRect*, const SkPaint*);
127     void drawShadowRec(const SkPath&, const SkDrawShadowRec&);
128     void drawVectorDrawable(VectorDrawableRoot* tree);
129     void drawWebView(skiapipeline::FunctorDrawable*);
130 
131     template <typename T, typename... Args>
132     void* push(size_t, Args&&...);
133 
134     template <typename Fn, typename... Args>
135     void map(const Fn[], Args...) const;
136 
137     SkAutoTMalloc<uint8_t> fBytes;
138     size_t fUsed = 0;
139     size_t fReserved = 0;
140 
141     bool mHasText : 1;
142 };
143 
144 class RecordingCanvas final : public SkCanvasVirtualEnforcer<SkNoDrawCanvas> {
145 public:
146     RecordingCanvas();
147     void reset(DisplayListData*, const SkIRect& bounds);
148 
149     sk_sp<SkSurface> onNewSurface(const SkImageInfo&, const SkSurfaceProps&) override;
150 
151     void willSave() override;
152     SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec&) override;
153     void willRestore() override;
154     bool onDoSaveBehind(const SkRect*) override;
155 
156     void onFlush() override;
157 
158     void didConcat44(const SkScalar[16]) override;
159     void didConcat(const SkMatrix&) override;
160     void didSetMatrix(const SkMatrix&) override;
161     void didScale(SkScalar, SkScalar) override;
162     void didTranslate(SkScalar, SkScalar) override;
163 
164     void onClipRect(const SkRect&, SkClipOp, ClipEdgeStyle) override;
165     void onClipRRect(const SkRRect&, SkClipOp, ClipEdgeStyle) override;
166     void onClipPath(const SkPath&, SkClipOp, ClipEdgeStyle) override;
167     void onClipRegion(const SkRegion&, SkClipOp) override;
168 
169     void onDrawPaint(const SkPaint&) override;
170     void onDrawBehind(const SkPaint&) override;
171     void onDrawPath(const SkPath&, const SkPaint&) override;
172     void onDrawRect(const SkRect&, const SkPaint&) override;
173     void onDrawRegion(const SkRegion&, const SkPaint&) override;
174     void onDrawOval(const SkRect&, const SkPaint&) override;
175     void onDrawArc(const SkRect&, SkScalar, SkScalar, bool, const SkPaint&) override;
176     void onDrawRRect(const SkRRect&, const SkPaint&) override;
177     void onDrawDRRect(const SkRRect&, const SkRRect&, const SkPaint&) override;
178 
179     void onDrawDrawable(SkDrawable*, const SkMatrix*) override;
180     void onDrawPicture(const SkPicture*, const SkMatrix*, const SkPaint*) override;
181     void onDrawAnnotation(const SkRect&, const char[], SkData*) override;
182 
183     void onDrawTextBlob(const SkTextBlob*, SkScalar, SkScalar, const SkPaint&) override;
184 
185     void onDrawBitmap(const SkBitmap&, SkScalar, SkScalar, const SkPaint*) override;
186     void onDrawBitmapLattice(const SkBitmap&, const Lattice&, const SkRect&,
187                              const SkPaint*) override;
188     void onDrawBitmapNine(const SkBitmap&, const SkIRect&, const SkRect&, const SkPaint*) override;
189     void onDrawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&, const SkPaint*,
190                           SrcRectConstraint) override;
191 
192     void drawImage(const sk_sp<SkImage>& image, SkScalar left, SkScalar top, const SkPaint* paint,
193                    BitmapPalette pallete);
194 
195     void drawImageRect(const sk_sp<SkImage>& image, const SkRect& src, const SkRect& dst,
196                        const SkPaint* paint, SrcRectConstraint constraint, BitmapPalette palette);
197     void drawImageLattice(const sk_sp<SkImage>& image, const Lattice& lattice, const SkRect& dst,
198                           const SkPaint* paint, BitmapPalette palette);
199 
200     void onDrawImage(const SkImage*, SkScalar, SkScalar, const SkPaint*) override;
201     void onDrawImageLattice(const SkImage*, const Lattice&, const SkRect&, const SkPaint*) override;
202     void onDrawImageNine(const SkImage*, const SkIRect&, const SkRect&, const SkPaint*) override;
203     void onDrawImageRect(const SkImage*, const SkRect*, const SkRect&, const SkPaint*,
204                          SrcRectConstraint) override;
205 
206     void onDrawPatch(const SkPoint[12], const SkColor[4], const SkPoint[4], SkBlendMode,
207                      const SkPaint&) override;
208     void onDrawPoints(PointMode, size_t count, const SkPoint pts[], const SkPaint&) override;
209     void onDrawVerticesObject(const SkVertices*, const SkVertices::Bone bones[], int boneCount,
210                               SkBlendMode, const SkPaint&) override;
211     void onDrawAtlas(const SkImage*, const SkRSXform[], const SkRect[], const SkColor[], int,
212                      SkBlendMode, const SkRect*, const SkPaint*) override;
213     void onDrawShadowRec(const SkPath&, const SkDrawShadowRec&) override;
214 
215     void drawVectorDrawable(VectorDrawableRoot* tree);
216     void drawWebView(skiapipeline::FunctorDrawable*);
217 
218     /**
219      * If "isClipMayBeComplex" returns false, it is guaranteed the current clip is a rectangle.
220      * If the return value is true, then clip may or may not be complex (there is no guarantee).
221      */
isClipMayBeComplex()222     inline bool isClipMayBeComplex() { return mClipMayBeComplex; }
223 
224 private:
225     typedef SkCanvasVirtualEnforcer<SkNoDrawCanvas> INHERITED;
226 
setClipMayBeComplex()227     inline void setClipMayBeComplex() {
228         if (!mClipMayBeComplex) {
229             mComplexSaveCount = mSaveCount;
230             mClipMayBeComplex = true;
231         }
232     }
233 
234     DisplayListData* fDL;
235 
236     /**
237      * mClipMayBeComplex tracks if the current clip is a rectangle. This flag is used to promote
238      * FunctorDrawable to a layer, if it is clipped by a non-rect.
239      */
240     bool mClipMayBeComplex = false;
241 
242     /**
243      * mSaveCount is the current level of our save tree.
244      */
245     int mSaveCount = 0;
246 
247     /**
248      * mComplexSaveCount is the first save level, which has a complex clip. Every level below
249      * mComplexSaveCount is assumed to have a complex clip and every level above mComplexSaveCount
250      * is guaranteed to not be complex.
251      */
252     int mComplexSaveCount = 0;
253 };
254 
255 }  // namespace uirenderer
256 }  // namespace android
257