1 | // Copyright 2013 The Flutter Authors. All rights reserved. |
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | #ifndef FLUTTER_DISPLAY_LIST_DL_CANVAS_H_ |
6 | #define FLUTTER_DISPLAY_LIST_DL_CANVAS_H_ |
7 | |
8 | #include "flutter/display_list/dl_blend_mode.h" |
9 | #include "flutter/display_list/dl_paint.h" |
10 | #include "flutter/display_list/dl_vertices.h" |
11 | #include "flutter/display_list/image/dl_image.h" |
12 | |
13 | #include "third_party/skia/include/core/SkM44.h" |
14 | #include "third_party/skia/include/core/SkMatrix.h" |
15 | #include "third_party/skia/include/core/SkPath.h" |
16 | #include "third_party/skia/include/core/SkRRect.h" |
17 | #include "third_party/skia/include/core/SkRSXform.h" |
18 | #include "third_party/skia/include/core/SkRect.h" |
19 | #include "third_party/skia/include/core/SkTextBlob.h" |
20 | |
21 | namespace flutter { |
22 | |
23 | // The primary class used to express rendering operations in the |
24 | // DisplayList ecosystem. This class is an API-only virtual class and |
25 | // can be used to talk to a DisplayListBuilder to record a series of |
26 | // rendering operations, or it could be the public facing API of an |
27 | // adapter that forwards the calls to another rendering module, like |
28 | // Skia. |
29 | // |
30 | // Developers familiar with Skia's SkCanvas API will be immediately |
31 | // familiar with the methods below as they follow that API closely |
32 | // but with DisplayList objects and values used as data instead. |
33 | class DlCanvas { |
34 | public: |
35 | enum class ClipOp { |
36 | kDifference, |
37 | kIntersect, |
38 | }; |
39 | |
40 | enum class PointMode { |
41 | kPoints, //!< draw each point separately |
42 | kLines, //!< draw each separate pair of points as a line segment |
43 | kPolygon, //!< draw each pair of overlapping points as a line segment |
44 | }; |
45 | |
46 | enum class SrcRectConstraint { |
47 | kStrict, |
48 | kFast, |
49 | }; |
50 | |
51 | virtual ~DlCanvas() = default; |
52 | |
53 | virtual SkISize GetBaseLayerSize() const = 0; |
54 | virtual SkImageInfo GetImageInfo() const = 0; |
55 | |
56 | virtual void Save() = 0; |
57 | virtual void SaveLayer(const SkRect* bounds, |
58 | const DlPaint* paint = nullptr, |
59 | const DlImageFilter* backdrop = nullptr) = 0; |
60 | virtual void Restore() = 0; |
61 | virtual int GetSaveCount() const = 0; |
62 | virtual void RestoreToCount(int restore_count) = 0; |
63 | |
64 | virtual void Translate(SkScalar tx, SkScalar ty) = 0; |
65 | virtual void Scale(SkScalar sx, SkScalar sy) = 0; |
66 | virtual void Rotate(SkScalar degrees) = 0; |
67 | virtual void Skew(SkScalar sx, SkScalar sy) = 0; |
68 | |
69 | // clang-format off |
70 | |
71 | // 2x3 2D affine subset of a 4x4 transform in row major order |
72 | virtual void Transform2DAffine(SkScalar mxx, SkScalar mxy, SkScalar mxt, |
73 | SkScalar myx, SkScalar myy, SkScalar myt) = 0; |
74 | // full 4x4 transform in row major order |
75 | virtual void TransformFullPerspective( |
76 | SkScalar mxx, SkScalar mxy, SkScalar mxz, SkScalar mxt, |
77 | SkScalar myx, SkScalar myy, SkScalar myz, SkScalar myt, |
78 | SkScalar mzx, SkScalar mzy, SkScalar mzz, SkScalar mzt, |
79 | SkScalar mwx, SkScalar mwy, SkScalar mwz, SkScalar mwt) = 0; |
80 | // clang-format on |
81 | virtual void TransformReset() = 0; |
82 | virtual void Transform(const SkMatrix* matrix) = 0; |
83 | virtual void Transform(const SkM44* matrix44) = 0; |
84 | virtual void Transform(const SkMatrix& matrix) { Transform(matrix: &matrix); } |
85 | virtual void Transform(const SkM44& matrix44) { Transform(matrix44: &matrix44); } |
86 | virtual void SetTransform(const SkMatrix* matrix) = 0; |
87 | virtual void SetTransform(const SkM44* matrix44) = 0; |
88 | virtual void SetTransform(const SkMatrix& matrix) { SetTransform(&matrix); } |
89 | virtual void SetTransform(const SkM44& matrix44) { SetTransform(&matrix44); } |
90 | |
91 | /// Returns the 4x4 full perspective transform representing all transform |
92 | /// operations executed so far in this DisplayList within the enclosing |
93 | /// save stack. |
94 | virtual SkM44 GetTransformFullPerspective() const = 0; |
95 | /// Returns the 3x3 partial perspective transform representing all transform |
96 | /// operations executed so far in this DisplayList within the enclosing |
97 | /// save stack. |
98 | virtual SkMatrix GetTransform() const = 0; |
99 | |
100 | virtual void ClipRect(const SkRect& rect, |
101 | ClipOp clip_op = ClipOp::kIntersect, |
102 | bool is_aa = false) = 0; |
103 | virtual void ClipRRect(const SkRRect& rrect, |
104 | ClipOp clip_op = ClipOp::kIntersect, |
105 | bool is_aa = false) = 0; |
106 | virtual void ClipPath(const SkPath& path, |
107 | ClipOp clip_op = ClipOp::kIntersect, |
108 | bool is_aa = false) = 0; |
109 | |
110 | /// Conservative estimate of the bounds of all outstanding clip operations |
111 | /// measured in the coordinate space within which this DisplayList will |
112 | /// be rendered. |
113 | virtual SkRect GetDestinationClipBounds() const = 0; |
114 | /// Conservative estimate of the bounds of all outstanding clip operations |
115 | /// transformed into the local coordinate space in which currently |
116 | /// recorded rendering operations are interpreted. |
117 | virtual SkRect GetLocalClipBounds() const = 0; |
118 | |
119 | /// Return true iff the supplied bounds are easily shown to be outside |
120 | /// of the current clip bounds. This method may conservatively return |
121 | /// false if it cannot make the determination. |
122 | virtual bool QuickReject(const SkRect& bounds) const = 0; |
123 | |
124 | virtual void DrawPaint(const DlPaint& paint) = 0; |
125 | virtual void DrawColor(DlColor color, |
126 | DlBlendMode mode = DlBlendMode::kSrcOver) = 0; |
127 | void Clear(DlColor color) { DrawColor(color, mode: DlBlendMode::kSrc); } |
128 | virtual void DrawLine(const SkPoint& p0, |
129 | const SkPoint& p1, |
130 | const DlPaint& paint) = 0; |
131 | virtual void DrawRect(const SkRect& rect, const DlPaint& paint) = 0; |
132 | virtual void DrawOval(const SkRect& bounds, const DlPaint& paint) = 0; |
133 | virtual void DrawCircle(const SkPoint& center, |
134 | SkScalar radius, |
135 | const DlPaint& paint) = 0; |
136 | virtual void DrawRRect(const SkRRect& rrect, const DlPaint& paint) = 0; |
137 | virtual void DrawDRRect(const SkRRect& outer, |
138 | const SkRRect& inner, |
139 | const DlPaint& paint) = 0; |
140 | virtual void DrawPath(const SkPath& path, const DlPaint& paint) = 0; |
141 | virtual void DrawArc(const SkRect& bounds, |
142 | SkScalar start, |
143 | SkScalar sweep, |
144 | bool useCenter, |
145 | const DlPaint& paint) = 0; |
146 | virtual void DrawPoints(PointMode mode, |
147 | uint32_t count, |
148 | const SkPoint pts[], |
149 | const DlPaint& paint) = 0; |
150 | virtual void DrawVertices(const DlVertices* vertices, |
151 | DlBlendMode mode, |
152 | const DlPaint& paint) = 0; |
153 | void DrawVertices(const std::shared_ptr<const DlVertices> vertices, |
154 | DlBlendMode mode, |
155 | const DlPaint& paint) { |
156 | DrawVertices(vertices: vertices.get(), mode, paint); |
157 | } |
158 | virtual void DrawImage(const sk_sp<DlImage>& image, |
159 | const SkPoint point, |
160 | DlImageSampling sampling, |
161 | const DlPaint* paint = nullptr) = 0; |
162 | virtual void DrawImageRect( |
163 | const sk_sp<DlImage>& image, |
164 | const SkRect& src, |
165 | const SkRect& dst, |
166 | DlImageSampling sampling, |
167 | const DlPaint* paint = nullptr, |
168 | SrcRectConstraint constraint = SrcRectConstraint::kFast) = 0; |
169 | virtual void DrawImageRect( |
170 | const sk_sp<DlImage>& image, |
171 | const SkIRect& src, |
172 | const SkRect& dst, |
173 | DlImageSampling sampling, |
174 | const DlPaint* paint = nullptr, |
175 | SrcRectConstraint constraint = SrcRectConstraint::kFast) { |
176 | DrawImageRect(image, src: SkRect::Make(irect: src), dst, sampling, paint, constraint); |
177 | } |
178 | virtual void DrawImageRect( |
179 | const sk_sp<DlImage>& image, |
180 | const SkRect& dst, |
181 | DlImageSampling sampling, |
182 | const DlPaint* paint = nullptr, |
183 | SrcRectConstraint constraint = SrcRectConstraint::kFast) { |
184 | DrawImageRect(image, src: image->bounds(), dst, sampling, paint, constraint); |
185 | } |
186 | virtual void DrawImageNine(const sk_sp<DlImage>& image, |
187 | const SkIRect& center, |
188 | const SkRect& dst, |
189 | DlFilterMode filter, |
190 | const DlPaint* paint = nullptr) = 0; |
191 | virtual void DrawAtlas(const sk_sp<DlImage>& atlas, |
192 | const SkRSXform xform[], |
193 | const SkRect tex[], |
194 | const DlColor colors[], |
195 | int count, |
196 | DlBlendMode mode, |
197 | DlImageSampling sampling, |
198 | const SkRect* cullRect, |
199 | const DlPaint* paint = nullptr) = 0; |
200 | virtual void DrawDisplayList(const sk_sp<DisplayList> display_list, |
201 | SkScalar opacity = SK_Scalar1) = 0; |
202 | virtual void DrawTextBlob(const sk_sp<SkTextBlob>& blob, |
203 | SkScalar x, |
204 | SkScalar y, |
205 | const DlPaint& paint) = 0; |
206 | virtual void DrawShadow(const SkPath& path, |
207 | const DlColor color, |
208 | const SkScalar elevation, |
209 | bool transparent_occluder, |
210 | SkScalar dpr) = 0; |
211 | |
212 | virtual void Flush() = 0; |
213 | |
214 | static constexpr SkScalar kShadowLightHeight = 600; |
215 | static constexpr SkScalar kShadowLightRadius = 800; |
216 | |
217 | static SkRect ComputeShadowBounds(const SkPath& path, |
218 | float elevation, |
219 | SkScalar dpr, |
220 | const SkMatrix& ctm); |
221 | }; |
222 | |
223 | class DlAutoCanvasRestore { |
224 | public: |
225 | DlAutoCanvasRestore(DlCanvas* canvas, bool do_save) : canvas_(canvas) { |
226 | if (canvas) { |
227 | canvas_ = canvas; |
228 | restore_count_ = canvas->GetSaveCount(); |
229 | if (do_save) { |
230 | canvas_->Save(); |
231 | } |
232 | } else { |
233 | canvas_ = nullptr; |
234 | restore_count_ = 0; |
235 | } |
236 | } |
237 | |
238 | ~DlAutoCanvasRestore() { Restore(); } |
239 | |
240 | void Restore() { |
241 | if (canvas_) { |
242 | canvas_->RestoreToCount(restore_count: restore_count_); |
243 | canvas_ = nullptr; |
244 | } |
245 | } |
246 | |
247 | private: |
248 | DlCanvas* canvas_; |
249 | int restore_count_; |
250 | |
251 | FML_DISALLOW_COPY_ASSIGN_AND_MOVE(DlAutoCanvasRestore); |
252 | }; |
253 | |
254 | } // namespace flutter |
255 | |
256 | #endif // FLUTTER_DISPLAY_LIST_DL_CANVAS_H_ |
257 | |