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