Flutter Impeller
canvas_recorder.h
Go to the documentation of this file.
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_IMPELLER_AIKS_CANVAS_RECORDER_H_
6 #define FLUTTER_IMPELLER_AIKS_CANVAS_RECORDER_H_
7 
8 #include <cstdint>
9 
10 #include "impeller/aiks/canvas.h"
11 
12 #define FLT_CANVAS_RECORDER_OP_ARG(name) \
13  CanvasRecorderOp::k##name, &Canvas::name
14 
15 namespace impeller {
16 /// TODO(tbd): These are very similar to `flutter::DisplayListOpType`. When
17 /// golden tests can be written at a higher level, migrate these to
18 /// flutter::DisplayListOpType.
19 enum CanvasRecorderOp : uint16_t {
51 };
52 
53 // Canvas recorder should only be used when IMPELLER_TRACE_CANVAS is defined
54 // (never in production code).
55 #ifdef IMPELLER_TRACE_CANVAS
56 /// Static polymorphic replacement for impeller::Canvas that records methods
57 /// called on an impeller::Canvas and forwards it to a real instance.
58 /// TODO(https://github.com/flutter/flutter/issues/135718): Move this recorder
59 /// to the DisplayList level when golden tests can be written at the ui.Canvas
60 /// layer.
61 template <typename Serializer>
62 class CanvasRecorder {
63  public:
64  CanvasRecorder() : canvas_() { serializer_.Write(CanvasRecorderOp::kNew); }
65 
66  explicit CanvasRecorder(Rect cull_rect) : canvas_(cull_rect) {
67  serializer_.Write(CanvasRecorderOp::kNew);
68  }
69 
70  explicit CanvasRecorder(IRect cull_rect) : canvas_(cull_rect) {
71  serializer_.Write(CanvasRecorderOp::kNew);
72  }
73 
74  ~CanvasRecorder() {}
75 
76  const Serializer& GetSerializer() const { return serializer_; }
77 
78  template <typename ReturnType>
79  ReturnType ExecuteAndSerialize(CanvasRecorderOp op,
80  ReturnType (Canvas::*canvasMethod)()) {
81  serializer_.Write(op);
82  return (canvas_.*canvasMethod)();
83  }
84 
85  template <typename FuncType, typename... Args>
86  auto ExecuteAndSerialize(CanvasRecorderOp op,
87  FuncType canvasMethod,
88  Args&&... args)
89  -> decltype((std::declval<Canvas>().*
90  canvasMethod)(std::forward<Args>(args)...)) {
91  // Serialize each argument
92  (serializer_.Write(std::forward<Args>(args)), ...);
93  serializer_.Write(op);
94  return (canvas_.*canvasMethod)(std::forward<Args>(args)...);
95  }
96 
97  template <typename FuncType, typename... Args>
98  auto ExecuteAndSkipArgSerialize(CanvasRecorderOp op,
99  FuncType canvasMethod,
100  Args&&... args)
101  -> decltype((std::declval<Canvas>().*
102  canvasMethod)(std::forward<Args>(args)...)) {
103  serializer_.Write(op);
104  return (canvas_.*canvasMethod)(std::forward<Args>(args)...);
105  }
106 
107  //////////////////////////////////////////////////////////////////////////////
108  // Canvas Static Polymorphism
109  // ////////////////////////////////////////////////
110  //////////////////////////////////////////////////////////////////////////////
111 
112  void Save() {
113  return ExecuteAndSerialize(CanvasRecorderOp::kSave, &Canvas::Save);
114  }
115 
116  void SaveLayer(
117  const Paint& paint,
118  std::optional<Rect> bounds = std::nullopt,
119  const std::shared_ptr<ImageFilter>& backdrop_filter = nullptr,
121  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(SaveLayer), paint,
122  bounds, backdrop_filter, bounds_promise);
123  }
124 
125  bool Restore() {
126  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Restore));
127  }
128 
129  size_t GetSaveCount() const { return canvas_.GetSaveCount(); }
130 
131  void RestoreToCount(size_t count) {
132  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(RestoreToCount),
133  count);
134  }
135 
136  const Matrix& GetCurrentTransform() const {
137  return canvas_.GetCurrentTransform();
138  }
139 
140  const std::optional<Rect> GetCurrentLocalCullingBounds() const {
141  return canvas_.GetCurrentLocalCullingBounds();
142  }
143 
144  void ResetTransform() {
145  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(ResetTransform));
146  }
147 
148  void Transform(const Matrix& transform) {
149  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Transform),
150  transform);
151  }
152 
153  void Concat(const Matrix& transform) {
154  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Concat), transform);
155  }
156 
157  void PreConcat(const Matrix& transform) {
158  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(PreConcat),
159  transform);
160  }
161 
162  void Translate(const Vector3& offset) {
163  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Translate), offset);
164  }
165 
166  void Scale(const Vector2& scale) {
167  return ExecuteAndSerialize(
169  static_cast<void (Canvas::*)(const Vector2&)>(&Canvas::Scale), scale);
170  }
171 
172  void Scale(const Vector3& scale) {
173  return ExecuteAndSerialize(
175  static_cast<void (Canvas::*)(const Vector3&)>(&Canvas::Scale), scale);
176  }
177 
178  void Skew(Scalar sx, Scalar sy) {
179  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Skew), sx, sy);
180  }
181 
182  void Rotate(Radians radians) {
183  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Rotate), radians);
184  }
185 
186  void DrawPath(Path path, const Paint& paint) {
187  serializer_.Write(path);
188  serializer_.Write(paint);
189  return ExecuteAndSkipArgSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawPath),
190  std::move(path), paint);
191  }
192 
193  void DrawPaint(const Paint& paint) {
194  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawPaint), paint);
195  }
196 
197  void DrawLine(const Point& p0, const Point& p1, const Paint& paint) {
198  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawLine), p0, p1,
199  paint);
200  }
201 
202  void DrawRect(Rect rect, const Paint& paint) {
203  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawRect), rect,
204  paint);
205  }
206 
207  void DrawOval(const Rect& rect, const Paint& paint) {
208  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawOval), rect,
209  paint);
210  }
211 
212  void DrawRRect(const Rect& rect,
213  const Size& corner_radii,
214  const Paint& paint) {
215  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawRRect), rect,
216  corner_radii, paint);
217  }
218 
219  void DrawCircle(Point center, Scalar radius, const Paint& paint) {
220  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawCircle), center,
221  radius, paint);
222  }
223 
224  void DrawPoints(std::vector<Point> points,
225  Scalar radius,
226  const Paint& paint,
227  PointStyle point_style) {
228  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawPoints), points,
229  radius, paint, point_style);
230  }
231 
232  void DrawImage(const std::shared_ptr<Image>& image,
233  Point offset,
234  const Paint& paint,
235  SamplerDescriptor sampler = {}) {
236  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawImage), image,
237  offset, paint, sampler);
238  }
239 
240  void DrawImageRect(
241  const std::shared_ptr<Image>& image,
242  Rect source,
243  Rect dest,
244  const Paint& paint,
245  SamplerDescriptor sampler = {},
246  SourceRectConstraint src_rect_constraint = SourceRectConstraint::kFast) {
247  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawImageRect), image,
248  source, dest, paint, sampler,
249  src_rect_constraint);
250  }
251 
252  void ClipPath(
253  Path path,
255  serializer_.Write(path);
256  serializer_.Write(clip_op);
257  return ExecuteAndSkipArgSerialize(FLT_CANVAS_RECORDER_OP_ARG(ClipPath),
258  std::move(path), clip_op);
259  }
260 
261  void ClipRect(
262  const Rect& rect,
264  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(ClipRect), rect,
265  clip_op);
266  }
267 
268  void ClipOval(
269  const Rect& bounds,
271  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(ClipOval), bounds,
272  clip_op);
273  }
274 
275  void ClipRRect(
276  const Rect& rect,
277  const Size& corner_radii,
279  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(ClipRRect), rect,
280  corner_radii, clip_op);
281  }
282 
283  void DrawTextFrame(const std::shared_ptr<TextFrame>& text_frame,
284  Point position,
285  const Paint& paint) {
286  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawTextFrame),
287  text_frame, position, paint);
288  }
289 
290  void DrawVertices(const std::shared_ptr<VerticesGeometry>& vertices,
291  BlendMode blend_mode,
292  const Paint& paint) {
293  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawVertices),
294  vertices, blend_mode, paint);
295  }
296 
297  void DrawAtlas(const std::shared_ptr<Image>& atlas,
298  std::vector<Matrix> transforms,
299  std::vector<Rect> texture_coordinates,
300  std::vector<Color> colors,
301  BlendMode blend_mode,
302  SamplerDescriptor sampler,
303  std::optional<Rect> cull_rect,
304  const Paint& paint) {
305  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawAtlas), //
306  atlas, //
307  transforms, //
308  texture_coordinates, //
309  colors, //
310  blend_mode, //
311  sampler, //
312  cull_rect, //
313  paint);
314  }
315 
316  Picture EndRecordingAsPicture() { return canvas_.EndRecordingAsPicture(); }
317 
318  private:
319  Canvas canvas_;
320  Serializer serializer_;
321 };
322 #endif
323 
324 } // namespace impeller
325 
326 #endif // FLUTTER_IMPELLER_AIKS_CANVAS_RECORDER_H_
impeller::Entity::ClipOperation::kIntersect
@ kIntersect
impeller::kResetTransform
@ kResetTransform
Definition: canvas_recorder.h:25
impeller::kPreConcat
@ kPreConcat
Definition: canvas_recorder.h:28
impeller::kDrawImage
@ kDrawImage
Definition: canvas_recorder.h:42
impeller::kClipPath
@ kClipPath
Definition: canvas_recorder.h:44
impeller::kClipOval
@ kClipOval
Definition: canvas_recorder.h:46
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::SourceRectConstraint::kFast
@ kFast
Faster, but may sample outside the bounds of the source rectangle.
impeller::kConcat
@ kConcat
Definition: canvas_recorder.h:27
impeller::BlendMode
BlendMode
Definition: color.h:59
impeller::PointStyle
PointStyle
Definition: canvas.h:41
impeller::kRotate
@ kRotate
Definition: canvas_recorder.h:33
impeller::Vector2
Point Vector2
Definition: point.h:320
impeller::ContentBoundsPromise
ContentBoundsPromise
Definition: entity_pass.h:28
impeller::ContentBoundsPromise::kUnknown
@ kUnknown
The caller makes no claims related to the size of the bounds.
impeller::Size
TSize< Scalar > Size
Definition: size.h:137
impeller::kSave
@ kSave
Definition: canvas_recorder.h:21
impeller::kDrawCircle
@ kDrawCircle
Definition: canvas_recorder.h:40
impeller::kDrawTextFrame
@ kDrawTextFrame
Definition: canvas_recorder.h:48
impeller::kScale2
@ kScale2
Definition: canvas_recorder.h:30
impeller::Point
TPoint< Scalar > Point
Definition: point.h:316
impeller::Canvas::Scale
void Scale(const Vector2 &scale)
Definition: canvas.cc:264
impeller::Canvas::Save
void Save()
Definition: canvas.cc:136
impeller::kDrawRect
@ kDrawRect
Definition: canvas_recorder.h:37
impeller::kSkew
@ kSkew
Definition: canvas_recorder.h:32
impeller::kClipRRect
@ kClipRRect
Definition: canvas_recorder.h:47
impeller::SourceRectConstraint
SourceRectConstraint
Controls the behavior of the source rectangle given to DrawImageRect.
Definition: canvas.h:50
impeller::kDrawImageRect
@ kDrawImageRect
Definition: canvas_recorder.h:43
canvas.h
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:661
impeller::kTransform
@ kTransform
Definition: canvas_recorder.h:26
impeller::kDrawAtlas
@ kDrawAtlas
Definition: canvas_recorder.h:50
impeller::IRect
TRect< int64_t > IRect
Definition: rect.h:662
impeller::kDrawPaint
@ kDrawPaint
Definition: canvas_recorder.h:35
impeller::kNew
@ kNew
Definition: canvas_recorder.h:20
impeller::kSaveLayer
@ kSaveLayer
Definition: canvas_recorder.h:22
impeller::kDrawPoints
@ kDrawPoints
Definition: canvas_recorder.h:41
scale
const Scalar scale
Definition: stroke_path_geometry.cc:297
impeller::Entity::ClipOperation
ClipOperation
Definition: entity.h:61
impeller::kDrawOval
@ kDrawOval
Definition: canvas_recorder.h:38
impeller::kScale3
@ kScale3
Definition: canvas_recorder.h:31
offset
Point offset
Definition: stroke_path_geometry.cc:300
impeller::kDrawVertices
@ kDrawVertices
Definition: canvas_recorder.h:49
impeller::kDrawLine
@ kDrawLine
Definition: canvas_recorder.h:36
impeller::kDrawPath
@ kDrawPath
Definition: canvas_recorder.h:34
impeller::kDrawRRect
@ kDrawRRect
Definition: canvas_recorder.h:39
impeller
Definition: aiks_blur_unittests.cc:20
impeller::kRestore
@ kRestore
Definition: canvas_recorder.h:23
impeller::kTranslate
@ kTranslate
Definition: canvas_recorder.h:29
impeller::CanvasRecorderOp
CanvasRecorderOp
Definition: canvas_recorder.h:19
impeller::kClipRect
@ kClipRect
Definition: canvas_recorder.h:45
FLT_CANVAS_RECORDER_OP_ARG
#define FLT_CANVAS_RECORDER_OP_ARG(name)
Definition: canvas_recorder.h:12
impeller::kRestoreToCount
@ kRestoreToCount
Definition: canvas_recorder.h:24