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 {
49 };
50 
51 // Canvas recorder should only be used when IMPELLER_TRACE_CANVAS is defined
52 // (never in production code).
53 #ifdef IMPELLER_TRACE_CANVAS
54 /// Static polymorphic replacement for impeller::Canvas that records methods
55 /// called on an impeller::Canvas and forwards it to a real instance.
56 /// TODO(https://github.com/flutter/flutter/issues/135718): Move this recorder
57 /// to the DisplayList level when golden tests can be written at the ui.Canvas
58 /// layer.
59 template <typename Serializer>
60 class CanvasRecorder {
61  public:
62  CanvasRecorder() : canvas_() { serializer_.Write(CanvasRecorderOp::kNew); }
63 
64  explicit CanvasRecorder(Rect cull_rect) : canvas_(cull_rect) {
65  serializer_.Write(CanvasRecorderOp::kNew);
66  }
67 
68  explicit CanvasRecorder(IRect cull_rect) : canvas_(cull_rect) {
69  serializer_.Write(CanvasRecorderOp::kNew);
70  }
71 
72  ~CanvasRecorder() {}
73 
74  const Serializer& GetSerializer() const { return serializer_; }
75 
76  template <typename ReturnType>
77  ReturnType ExecuteAndSerialize(CanvasRecorderOp op,
78  ReturnType (Canvas::*canvasMethod)()) {
79  serializer_.Write(op);
80  return (canvas_.*canvasMethod)();
81  }
82 
83  template <typename FuncType, typename... Args>
84  auto ExecuteAndSerialize(CanvasRecorderOp op,
85  FuncType canvasMethod,
86  Args&&... args)
87  -> decltype((std::declval<Canvas>().*
88  canvasMethod)(std::forward<Args>(args)...)) {
89  // Serialize each argument
90  (serializer_.Write(std::forward<Args>(args)), ...);
91  serializer_.Write(op);
92  return (canvas_.*canvasMethod)(std::forward<Args>(args)...);
93  }
94 
95  template <typename FuncType, typename... Args>
96  auto ExecuteAndSkipArgSerialize(CanvasRecorderOp op,
97  FuncType canvasMethod,
98  Args&&... args)
99  -> decltype((std::declval<Canvas>().*
100  canvasMethod)(std::forward<Args>(args)...)) {
101  serializer_.Write(op);
102  return (canvas_.*canvasMethod)(std::forward<Args>(args)...);
103  }
104 
105  //////////////////////////////////////////////////////////////////////////////
106  // Canvas Static Polymorphism
107  // ////////////////////////////////////////////////
108  //////////////////////////////////////////////////////////////////////////////
109 
110  void Save() {
111  return ExecuteAndSerialize(CanvasRecorderOp::kSave, &Canvas::Save);
112  }
113 
114  void SaveLayer(
115  const Paint& paint,
116  std::optional<Rect> bounds = std::nullopt,
117  const std::shared_ptr<ImageFilter>& backdrop_filter = nullptr) {
118  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(SaveLayer), paint,
119  bounds, backdrop_filter);
120  }
121 
122  bool Restore() {
123  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Restore));
124  }
125 
126  size_t GetSaveCount() const { return canvas_.GetSaveCount(); }
127 
128  void RestoreToCount(size_t count) {
129  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(RestoreToCount),
130  count);
131  }
132 
133  const Matrix& GetCurrentTransform() const {
134  return canvas_.GetCurrentTransform();
135  }
136 
137  const std::optional<Rect> GetCurrentLocalCullingBounds() const {
138  return canvas_.GetCurrentLocalCullingBounds();
139  }
140 
141  void ResetTransform() {
142  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(ResetTransform));
143  }
144 
145  void Transform(const Matrix& transform) {
146  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Transform),
147  transform);
148  }
149 
150  void Concat(const Matrix& transform) {
151  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Concat), transform);
152  }
153 
154  void PreConcat(const Matrix& transform) {
155  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(PreConcat),
156  transform);
157  }
158 
159  void Translate(const Vector3& offset) {
160  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Translate), offset);
161  }
162 
163  void Scale(const Vector2& scale) {
164  return ExecuteAndSerialize(
166  static_cast<void (Canvas::*)(const Vector2&)>(&Canvas::Scale), scale);
167  }
168 
169  void Scale(const Vector3& scale) {
170  return ExecuteAndSerialize(
172  static_cast<void (Canvas::*)(const Vector3&)>(&Canvas::Scale), scale);
173  }
174 
175  void Skew(Scalar sx, Scalar sy) {
176  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Skew), sx, sy);
177  }
178 
179  void Rotate(Radians radians) {
180  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(Rotate), radians);
181  }
182 
183  void DrawPath(Path path, const Paint& paint) {
184  serializer_.Write(path);
185  serializer_.Write(paint);
186  return ExecuteAndSkipArgSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawPath),
187  std::move(path), paint);
188  }
189 
190  void DrawPaint(const Paint& paint) {
191  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawPaint), paint);
192  }
193 
194  void DrawRect(Rect rect, const Paint& paint) {
195  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawRect), rect,
196  paint);
197  }
198 
199  void DrawRRect(const Rect& rect,
200  const Size& corner_radii,
201  const Paint& paint) {
202  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawRRect), rect,
203  corner_radii, paint);
204  }
205 
206  void DrawCircle(Point center, Scalar radius, const Paint& paint) {
207  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawCircle), center,
208  radius, paint);
209  }
210 
211  void DrawPoints(std::vector<Point> points,
212  Scalar radius,
213  const Paint& paint,
214  PointStyle point_style) {
215  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawPoints), points,
216  radius, paint, point_style);
217  }
218 
219  void DrawImage(const std::shared_ptr<Image>& image,
220  Point offset,
221  const Paint& paint,
222  SamplerDescriptor sampler = {}) {
223  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawImage), image,
224  offset, paint, sampler);
225  }
226 
227  void DrawImageRect(const std::shared_ptr<Image>& image,
228  Rect source,
229  Rect dest,
230  const Paint& paint,
231  SamplerDescriptor sampler = {}) {
232  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawImageRect), image,
233  source, dest, paint, sampler);
234  }
235 
236  void ClipPath(
237  Path path,
239  serializer_.Write(path);
240  serializer_.Write(clip_op);
241  return ExecuteAndSkipArgSerialize(FLT_CANVAS_RECORDER_OP_ARG(ClipPath),
242  std::move(path), clip_op);
243  }
244 
245  void ClipRect(
246  const Rect& rect,
248  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(ClipRect), rect,
249  clip_op);
250  }
251 
252  void ClipRRect(
253  const Rect& rect,
254  const Size& corner_radii,
256  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(ClipRRect), rect,
257  corner_radii, clip_op);
258  }
259 
260  void DrawPicture(const Picture& picture) {
261  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawPicture),
262  picture);
263  }
264 
265  void DrawTextFrame(const std::shared_ptr<TextFrame>& text_frame,
266  Point position,
267  const Paint& paint) {
268  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawTextFrame),
269  text_frame, position, paint);
270  }
271 
272  void DrawVertices(const std::shared_ptr<VerticesGeometry>& vertices,
273  BlendMode blend_mode,
274  const Paint& paint) {
275  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawVertices),
276  vertices, blend_mode, paint);
277  }
278 
279  void DrawAtlas(const std::shared_ptr<Image>& atlas,
280  std::vector<Matrix> transforms,
281  std::vector<Rect> texture_coordinates,
282  std::vector<Color> colors,
283  BlendMode blend_mode,
284  SamplerDescriptor sampler,
285  std::optional<Rect> cull_rect,
286  const Paint& paint) {
287  return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawAtlas), //
288  atlas, //
289  transforms, //
290  texture_coordinates, //
291  colors, //
292  blend_mode, //
293  sampler, //
294  cull_rect, //
295  paint);
296  }
297 
298  Picture EndRecordingAsPicture() { return canvas_.EndRecordingAsPicture(); }
299 
300  private:
301  Canvas canvas_;
302  Serializer serializer_;
303 };
304 #endif
305 
306 } // namespace impeller
307 
308 #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:40
impeller::kClipPath
@ kClipPath
Definition: canvas_recorder.h:42
impeller::Scalar
float Scalar
Definition: scalar.h:18
impeller::kConcat
@ kConcat
Definition: canvas_recorder.h:27
impeller::kDrawPicture
@ kDrawPicture
Definition: canvas_recorder.h:45
impeller::BlendMode
BlendMode
Definition: color.h:59
impeller::PointStyle
PointStyle
Definition: canvas.h:40
impeller::kRotate
@ kRotate
Definition: canvas_recorder.h:33
impeller::Vector2
Point Vector2
Definition: point.h:312
impeller::Size
TSize< Scalar > Size
Definition: size.h:137
impeller::kSave
@ kSave
Definition: canvas_recorder.h:21
impeller::kDrawCircle
@ kDrawCircle
Definition: canvas_recorder.h:38
impeller::kDrawTextFrame
@ kDrawTextFrame
Definition: canvas_recorder.h:46
impeller::kScale2
@ kScale2
Definition: canvas_recorder.h:30
impeller::Point
TPoint< Scalar > Point
Definition: point.h:308
impeller::Canvas::Scale
void Scale(const Vector2 &scale)
Definition: canvas.cc:222
impeller::Canvas::Save
void Save()
Definition: canvas.cc:132
impeller::kDrawRect
@ kDrawRect
Definition: canvas_recorder.h:36
impeller::kSkew
@ kSkew
Definition: canvas_recorder.h:32
impeller::kClipRRect
@ kClipRRect
Definition: canvas_recorder.h:44
impeller::kDrawImageRect
@ kDrawImageRect
Definition: canvas_recorder.h:41
canvas.h
impeller::Rect
TRect< Scalar > Rect
Definition: rect.h:488
impeller::kTransform
@ kTransform
Definition: canvas_recorder.h:26
impeller::kDrawAtlas
@ kDrawAtlas
Definition: canvas_recorder.h:48
impeller::IRect
TRect< int64_t > IRect
Definition: rect.h:489
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:39
impeller::Entity::ClipOperation
ClipOperation
Definition: entity.h:59
impeller::kScale3
@ kScale3
Definition: canvas_recorder.h:31
impeller::kDrawVertices
@ kDrawVertices
Definition: canvas_recorder.h:47
impeller::kDrawPath
@ kDrawPath
Definition: canvas_recorder.h:34
impeller::kDrawRRect
@ kDrawRRect
Definition: canvas_recorder.h:37
impeller
Definition: aiks_context.cc:10
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:43
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