Flutter Impeller
dl_dispatcher.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_DISPLAY_LIST_DL_DISPATCHER_H_
6 #define FLUTTER_IMPELLER_DISPLAY_LIST_DL_DISPATCHER_H_
7 
8 #include <memory>
9 
10 #include "flutter/display_list/dl_op_receiver.h"
11 #include "flutter/display_list/geometry/dl_geometry_types.h"
12 #include "flutter/display_list/geometry/dl_path.h"
13 #include "flutter/display_list/utils/dl_receiver_utils.h"
14 #include "fml/logging.h"
19 #include "impeller/geometry/rect.h"
20 
21 namespace impeller {
22 
29 
30 class DlDispatcherBase : public flutter::DlOpReceiver {
31  public:
32  // |flutter::DlOpReceiver|
33  void setAntiAlias(bool aa) override;
34 
35  // |flutter::DlOpReceiver|
36  void setDrawStyle(flutter::DlDrawStyle style) override;
37 
38  // |flutter::DlOpReceiver|
39  void setColor(flutter::DlColor color) override;
40 
41  // |flutter::DlOpReceiver|
42  void setStrokeWidth(DlScalar width) override;
43 
44  // |flutter::DlOpReceiver|
45  void setStrokeMiter(DlScalar limit) override;
46 
47  // |flutter::DlOpReceiver|
48  void setStrokeCap(flutter::DlStrokeCap cap) override;
49 
50  // |flutter::DlOpReceiver|
51  void setStrokeJoin(flutter::DlStrokeJoin join) override;
52 
53  // |flutter::DlOpReceiver|
54  void setColorSource(const flutter::DlColorSource* source) override;
55 
56  // |flutter::DlOpReceiver|
57  void setColorFilter(const flutter::DlColorFilter* filter) override;
58 
59  // |flutter::DlOpReceiver|
60  void setInvertColors(bool invert) override;
61 
62  // |flutter::DlOpReceiver|
63  void setBlendMode(flutter::DlBlendMode mode) override;
64 
65  // |flutter::DlOpReceiver|
66  void setMaskFilter(const flutter::DlMaskFilter* filter) override;
67 
68  // |flutter::DlOpReceiver|
69  void setImageFilter(const flutter::DlImageFilter* filter) override;
70 
71  // |flutter::DlOpReceiver|
72  void save(uint32_t total_content_depth) override;
73 
74  // |flutter::DlOpReceiver|
75  void saveLayer(const DlRect& bounds,
76  const flutter::SaveLayerOptions& options,
77  uint32_t total_content_depth,
78  flutter::DlBlendMode max_content_mode,
79  const flutter::DlImageFilter* backdrop,
80  std::optional<int64_t> backdrop_id) override;
81 
82  // |flutter::DlOpReceiver|
83  void restore() override;
84 
85  // |flutter::DlOpReceiver|
86  void translate(DlScalar tx, DlScalar ty) override;
87 
88  // |flutter::DlOpReceiver|
89  void scale(DlScalar sx, DlScalar sy) override;
90 
91  // |flutter::DlOpReceiver|
92  void rotate(DlScalar degrees) override;
93 
94  // |flutter::DlOpReceiver|
95  void skew(DlScalar sx, DlScalar sy) override;
96 
97  // |flutter::DlOpReceiver|
98  void transform2DAffine(DlScalar mxx,
99  DlScalar mxy,
100  DlScalar mxt,
101  DlScalar myx,
102  DlScalar myy,
103  DlScalar myt) override;
104 
105  // |flutter::DlOpReceiver|
107  DlScalar mxy,
108  DlScalar mxz,
109  DlScalar mxt,
110  DlScalar myx,
111  DlScalar myy,
112  DlScalar myz,
113  DlScalar myt,
114  DlScalar mzx,
115  DlScalar mzy,
116  DlScalar mzz,
117  DlScalar mzt,
118  DlScalar mwx,
119  DlScalar mwy,
120  DlScalar mwz,
121  DlScalar mwt) override;
122 
123  // |flutter::DlOpReceiver|
124  void transformReset() override;
125 
126  // |flutter::DlOpReceiver|
127  void clipRect(const DlRect& rect, ClipOp clip_op, bool is_aa) override;
128 
129  // |flutter::DlOpReceiver|
130  void clipOval(const DlRect& bounds, ClipOp clip_op, bool is_aa) override;
131 
132  // |flutter::DlOpReceiver|
133  void clipRoundRect(const DlRoundRect& rrect,
134  ClipOp clip_op,
135  bool is_aa) override;
136 
137  // |flutter::DlOpReceiver|
138  void clipPath(const DlPath& path, ClipOp clip_op, bool is_aa) override;
139 
140  // |flutter::DlOpReceiver|
141  void drawColor(flutter::DlColor color, flutter::DlBlendMode mode) override;
142 
143  // |flutter::DlOpReceiver|
144  void drawPaint() override;
145 
146  // |flutter::DlOpReceiver|
147  void drawLine(const DlPoint& p0, const DlPoint& p1) override;
148 
149  // |flutter::DlOpReceiver|
150  void drawDashedLine(const DlPoint& p0,
151  const DlPoint& p1,
152  DlScalar on_length,
153  DlScalar off_length) override;
154 
155  // |flutter::DlOpReceiver|
156  void drawRect(const DlRect& rect) override;
157 
158  // |flutter::DlOpReceiver|
159  void drawOval(const DlRect& bounds) override;
160 
161  // |flutter::DlOpReceiver|
162  void drawCircle(const DlPoint& center, DlScalar radius) override;
163 
164  // |flutter::DlOpReceiver|
165  void drawRoundRect(const DlRoundRect& rrect) override;
166 
167  // |flutter::DlOpReceiver|
168  void drawDiffRoundRect(const DlRoundRect& outer,
169  const DlRoundRect& inner) override;
170 
171  // |flutter::DlOpReceiver|
172  void drawPath(const DlPath& path) override;
173 
174  // |flutter::DlOpReceiver|
175  void drawArc(const DlRect& oval_bounds,
176  DlScalar start_degrees,
177  DlScalar sweep_degrees,
178  bool use_center) override;
179 
180  // |flutter::DlOpReceiver|
181  void drawPoints(PointMode mode,
182  uint32_t count,
183  const DlPoint points[]) override;
184 
185  // |flutter::DlOpReceiver|
186  void drawVertices(const std::shared_ptr<flutter::DlVertices>& vertices,
187  flutter::DlBlendMode dl_mode) override;
188 
189  // |flutter::DlOpReceiver|
190  void drawImage(const sk_sp<flutter::DlImage> image,
191  const DlPoint& point,
192  flutter::DlImageSampling sampling,
193  bool render_with_attributes) override;
194 
195  // |flutter::DlOpReceiver|
196  void drawImageRect(const sk_sp<flutter::DlImage> image,
197  const DlRect& src,
198  const DlRect& dst,
199  flutter::DlImageSampling sampling,
200  bool render_with_attributes,
201  SrcRectConstraint constraint) override;
202 
203  // |flutter::DlOpReceiver|
204  void drawImageNine(const sk_sp<flutter::DlImage> image,
205  const DlIRect& center,
206  const DlRect& dst,
207  flutter::DlFilterMode filter,
208  bool render_with_attributes) override;
209 
210  // |flutter::DlOpReceiver|
211  void drawAtlas(const sk_sp<flutter::DlImage> atlas,
212  const RSTransform xform[],
213  const DlRect tex[],
214  const flutter::DlColor colors[],
215  int count,
216  flutter::DlBlendMode mode,
217  flutter::DlImageSampling sampling,
218  const DlRect* cull_rect,
219  bool render_with_attributes) override;
220 
221  // |flutter::DlOpReceiver|
222  void drawDisplayList(const sk_sp<flutter::DisplayList> display_list,
223  DlScalar opacity) override;
224 
225  // |flutter::DlOpReceiver|
226  void drawTextBlob(const sk_sp<SkTextBlob> blob,
227  DlScalar x,
228  DlScalar y) override;
229 
230  // |flutter::DlOpReceiver|
231  void drawTextFrame(const std::shared_ptr<impeller::TextFrame>& text_frame,
232  DlScalar x,
233  DlScalar y) override;
234 
235  // |flutter::DlOpReceiver|
236  void drawShadow(const DlPath& path,
237  const flutter::DlColor color,
238  const DlScalar elevation,
239  bool transparent_occluder,
240  DlScalar dpr) override;
241 
242  virtual Canvas& GetCanvas() = 0;
243 
244  protected:
247 
248  static void SimplifyOrDrawPath(Canvas& canvas,
249  const DlPath& cache,
250  const Paint& paint);
251 };
252 
254  public:
256  RenderTarget& render_target,
257  bool is_onscreen,
258  bool has_root_backdrop_filter,
259  flutter::DlBlendMode max_root_blend_mode,
260  IRect cull_rect);
261 
262  ~CanvasDlDispatcher() = default;
263 
264  void SetBackdropData(std::unordered_map<int64_t, BackdropData> backdrop,
265  size_t backdrop_count);
266 
267  // |flutter::DlOpReceiver|
268  void save() override {
269  // This dispatcher should never be used with the save() variant
270  // that does not include the content_depth parameter.
271  FML_UNREACHABLE();
272  }
274 
275  // |flutter::DlOpReceiver|
276  void saveLayer(const DlRect& bounds,
277  const flutter::SaveLayerOptions options,
278  const flutter::DlImageFilter* backdrop,
279  std::optional<int64_t> backdrop_id) override {
280  // This dispatcher should never be used with the saveLayer() variant
281  // that does not include the content_depth parameter.
282  FML_UNREACHABLE();
283  }
285 
286  void FinishRecording() { canvas_.EndReplay(); }
287 
288  // |flutter::DlOpReceiver|
289  void drawVertices(const std::shared_ptr<flutter::DlVertices>& vertices,
290  flutter::DlBlendMode dl_mode) override;
291 
292  private:
293  Canvas canvas_;
294  const ContentContext& renderer_;
295 
296  Canvas& GetCanvas() override;
297 };
298 
299 /// Performs a first pass over the display list to collect infomation.
300 /// Collects things like text frames and backdrop filters.
301 class FirstPassDispatcher : public flutter::IgnoreAttributeDispatchHelper,
302  public flutter::IgnoreClipDispatchHelper,
303  public flutter::IgnoreDrawDispatchHelper {
304  public:
305  FirstPassDispatcher(const ContentContext& renderer,
306  const Matrix& initial_matrix,
307  const Rect cull_rect);
308 
310 
311  void save() override;
312 
313  void saveLayer(const DlRect& bounds,
314  const flutter::SaveLayerOptions options,
315  const flutter::DlImageFilter* backdrop,
316  std::optional<int64_t> backdrop_id) override;
317 
318  void restore() override;
319 
320  void translate(DlScalar tx, DlScalar ty) override;
321 
322  void scale(DlScalar sx, DlScalar sy) override;
323 
324  void rotate(DlScalar degrees) override;
325 
326  void skew(DlScalar sx, DlScalar sy) override;
327 
328  // clang-format off
329  // 2x3 2D affine subset of a 4x4 transform in row major order
330  void transform2DAffine(DlScalar mxx, DlScalar mxy, DlScalar mxt,
331  DlScalar myx, DlScalar myy, DlScalar myt) override;
332 
333  // full 4x4 transform in row major order
335  DlScalar mxx, DlScalar mxy, DlScalar mxz, DlScalar mxt,
336  DlScalar myx, DlScalar myy, DlScalar myz, DlScalar myt,
337  DlScalar mzx, DlScalar mzy, DlScalar mzz, DlScalar mzt,
338  DlScalar mwx, DlScalar mwy, DlScalar mwz, DlScalar mwt) override;
339 
340  void transformReset() override;
341 
342  void drawTextFrame(const std::shared_ptr<impeller::TextFrame>& text_frame,
343  DlScalar x,
344  DlScalar y) override;
345 
346  void drawDisplayList(const sk_sp<flutter::DisplayList> display_list,
347  DlScalar opacity) override;
348 
349  // |flutter::DlOpReceiver|
350  void setDrawStyle(flutter::DlDrawStyle style) override;
351 
352  // |flutter::DlOpReceiver|
353  void setColor(flutter::DlColor color) override;
354 
355  // |flutter::DlOpReceiver|
356  void setStrokeWidth(DlScalar width) override;
357 
358  // |flutter::DlOpReceiver|
359  void setStrokeMiter(DlScalar limit) override;
360 
361  // |flutter::DlOpReceiver|
362  void setStrokeCap(flutter::DlStrokeCap cap) override;
363 
364  // |flutter::DlOpReceiver|
365  void setStrokeJoin(flutter::DlStrokeJoin join) override;
366 
367  // |flutter::DlOpReceiver|
368  void setImageFilter(const flutter::DlImageFilter* filter) override;
369 
370  std::pair<std::unordered_map<int64_t, BackdropData>, size_t> TakeBackdropData();
371 
372  private:
373  const Rect GetCurrentLocalCullingBounds() const;
374 
375  const ContentContext& renderer_;
376  Matrix matrix_;
377  std::vector<Matrix> stack_;
378  std::unordered_map<int64_t, BackdropData> backdrop_data_;
379  // note: cull rects are always in the global coordinate space.
380  std::vector<Rect> cull_rect_state_;
381  bool has_image_filter_ = false;
382  size_t backdrop_count_ = 0;
383  Paint paint_;
384 };
385 
386 /// Render the provided display list to a texture with the given size.
387 std::shared_ptr<Texture> DisplayListToTexture(
388  const sk_sp<flutter::DisplayList>& display_list,
389  ISize size,
390  AiksContext& context,
391  bool reset_host_buffer = true,
392  bool generate_mips = false);
393 
394 /// @brief Render the provided display list to the render target.
395 ///
396 /// If [is_onscreen] is true, then the onscreen command buffer will be
397 /// submitted via Context::SubmitOnscreen.
398 bool RenderToTarget(ContentContext& context, RenderTarget render_target,
399  const sk_sp<flutter::DisplayList>& display_list,
400  SkIRect cull_rect,
401  bool reset_host_buffer,
402  bool is_onscreen = true);
403 
404 } // namespace impeller
405 
406 #endif // FLUTTER_IMPELLER_DISPLAY_LIST_DL_DISPATCHER_H_
void saveLayer(const DlRect &bounds, const flutter::SaveLayerOptions options, const flutter::DlImageFilter *backdrop, std::optional< int64_t > backdrop_id) override
CanvasDlDispatcher(ContentContext &renderer, RenderTarget &render_target, bool is_onscreen, bool has_root_backdrop_filter, flutter::DlBlendMode max_root_blend_mode, IRect cull_rect)
void drawVertices(const std::shared_ptr< flutter::DlVertices > &vertices, flutter::DlBlendMode dl_mode) override
void SetBackdropData(std::unordered_map< int64_t, BackdropData > backdrop, size_t backdrop_count)
void EndReplay()
Definition: canvas.cc:1742
void drawLine(const DlPoint &p0, const DlPoint &p1) override
void drawAtlas(const sk_sp< flutter::DlImage > atlas, const RSTransform xform[], const DlRect tex[], const flutter::DlColor colors[], int count, flutter::DlBlendMode mode, flutter::DlImageSampling sampling, const DlRect *cull_rect, bool render_with_attributes) override
void clipRoundRect(const DlRoundRect &rrect, ClipOp clip_op, bool is_aa) override
virtual Canvas & GetCanvas()=0
void drawDashedLine(const DlPoint &p0, const DlPoint &p1, DlScalar on_length, DlScalar off_length) override
void drawOval(const DlRect &bounds) override
void clipRect(const DlRect &rect, ClipOp clip_op, bool is_aa) override
void setImageFilter(const flutter::DlImageFilter *filter) override
void drawPath(const DlPath &path) override
void setStrokeCap(flutter::DlStrokeCap cap) override
void clipOval(const DlRect &bounds, ClipOp clip_op, bool is_aa) override
void skew(DlScalar sx, DlScalar sy) override
void setAntiAlias(bool aa) override
void transformFullPerspective(DlScalar mxx, DlScalar mxy, DlScalar mxz, DlScalar mxt, DlScalar myx, DlScalar myy, DlScalar myz, DlScalar myt, DlScalar mzx, DlScalar mzy, DlScalar mzz, DlScalar mzt, DlScalar mwx, DlScalar mwy, DlScalar mwz, DlScalar mwt) override
void setStrokeWidth(DlScalar width) override
void drawDiffRoundRect(const DlRoundRect &outer, const DlRoundRect &inner) override
void drawRoundRect(const DlRoundRect &rrect) override
void setStrokeJoin(flutter::DlStrokeJoin join) override
void drawTextBlob(const sk_sp< SkTextBlob > blob, DlScalar x, DlScalar y) override
void rotate(DlScalar degrees) override
void setColorFilter(const flutter::DlColorFilter *filter) override
void drawPoints(PointMode mode, uint32_t count, const DlPoint points[]) override
void drawImageRect(const sk_sp< flutter::DlImage > image, const DlRect &src, const DlRect &dst, flutter::DlImageSampling sampling, bool render_with_attributes, SrcRectConstraint constraint) override
void scale(DlScalar sx, DlScalar sy) override
void setDrawStyle(flutter::DlDrawStyle style) override
void drawShadow(const DlPath &path, const flutter::DlColor color, const DlScalar elevation, bool transparent_occluder, DlScalar dpr) override
void drawImage(const sk_sp< flutter::DlImage > image, const DlPoint &point, flutter::DlImageSampling sampling, bool render_with_attributes) override
void drawArc(const DlRect &oval_bounds, DlScalar start_degrees, DlScalar sweep_degrees, bool use_center) override
void saveLayer(const DlRect &bounds, const flutter::SaveLayerOptions &options, uint32_t total_content_depth, flutter::DlBlendMode max_content_mode, const flutter::DlImageFilter *backdrop, std::optional< int64_t > backdrop_id) override
void drawDisplayList(const sk_sp< flutter::DisplayList > display_list, DlScalar opacity) override
void transform2DAffine(DlScalar mxx, DlScalar mxy, DlScalar mxt, DlScalar myx, DlScalar myy, DlScalar myt) override
void setInvertColors(bool invert) override
void setColor(flutter::DlColor color) override
void save(uint32_t total_content_depth) override
void setStrokeMiter(DlScalar limit) override
void translate(DlScalar tx, DlScalar ty) override
void drawVertices(const std::shared_ptr< flutter::DlVertices > &vertices, flutter::DlBlendMode dl_mode) override
void drawCircle(const DlPoint &center, DlScalar radius) override
void drawTextFrame(const std::shared_ptr< impeller::TextFrame > &text_frame, DlScalar x, DlScalar y) override
void setMaskFilter(const flutter::DlMaskFilter *filter) override
void clipPath(const DlPath &path, ClipOp clip_op, bool is_aa) override
void setColorSource(const flutter::DlColorSource *source) override
void drawImageNine(const sk_sp< flutter::DlImage > image, const DlIRect &center, const DlRect &dst, flutter::DlFilterMode filter, bool render_with_attributes) override
void transformReset() override
void setBlendMode(flutter::DlBlendMode mode) override
void drawColor(flutter::DlColor color, flutter::DlBlendMode mode) override
void drawRect(const DlRect &rect) override
static void SimplifyOrDrawPath(Canvas &canvas, const DlPath &cache, const Paint &paint)
void setColor(flutter::DlColor color) override
void setStrokeCap(flutter::DlStrokeCap cap) override
void saveLayer(const DlRect &bounds, const flutter::SaveLayerOptions options, const flutter::DlImageFilter *backdrop, std::optional< int64_t > backdrop_id) override
void setDrawStyle(flutter::DlDrawStyle style) override
std::pair< std::unordered_map< int64_t, BackdropData >, size_t > TakeBackdropData()
void rotate(DlScalar degrees) override
void drawTextFrame(const std::shared_ptr< impeller::TextFrame > &text_frame, DlScalar x, DlScalar y) override
void setImageFilter(const flutter::DlImageFilter *filter) override
void setStrokeMiter(DlScalar limit) override
void transformFullPerspective(DlScalar mxx, DlScalar mxy, DlScalar mxz, DlScalar mxt, DlScalar myx, DlScalar myy, DlScalar myz, DlScalar myt, DlScalar mzx, DlScalar mzy, DlScalar mzz, DlScalar mzt, DlScalar mwx, DlScalar mwy, DlScalar mwz, DlScalar mwt) override
void scale(DlScalar sx, DlScalar sy) override
void translate(DlScalar tx, DlScalar ty) override
void skew(DlScalar sx, DlScalar sy) override
FirstPassDispatcher(const ContentContext &renderer, const Matrix &initial_matrix, const Rect cull_rect)
void drawDisplayList(const sk_sp< flutter::DisplayList > display_list, DlScalar opacity) override
void setStrokeWidth(DlScalar width) override
void setStrokeJoin(flutter::DlStrokeJoin join) override
void transform2DAffine(DlScalar mxx, DlScalar mxy, DlScalar mxt, DlScalar myx, DlScalar myy, DlScalar myt) override
int32_t x
std::shared_ptr< Texture > DisplayListToTexture(const sk_sp< flutter::DisplayList > &display_list, ISize size, AiksContext &context, bool reset_host_buffer, bool generate_mips)
Render the provided display list to a texture with the given size.
flutter::DlRect DlRect
Definition: dl_dispatcher.h:25
flutter::DlIRect DlIRect
Definition: dl_dispatcher.h:26
flutter::DlRoundRect DlRoundRect
Definition: dl_dispatcher.h:27
bool RenderToTarget(ContentContext &context, RenderTarget render_target, const sk_sp< flutter::DisplayList > &display_list, SkIRect cull_rect, bool reset_host_buffer, bool is_onscreen)
Render the provided display list to the render target.
flutter::DlPoint DlPoint
Definition: dl_dispatcher.h:24
flutter::DlPath DlPath
Definition: dl_dispatcher.h:28
flutter::DlScalar DlScalar
Definition: dl_dispatcher.h:23
A 4x4 matrix using column-major storage.
Definition: matrix.h:37