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
21namespace 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.
33class 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
223class 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

source code of flutter_engine/flutter/display_list/dl_canvas.h