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