Flutter Engine
 
Loading...
Searching...
No Matches
dl_builder.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_DISPLAY_LIST_DL_BUILDER_H_
6#define FLUTTER_DISPLAY_LIST_DL_BUILDER_H_
7
20#include "flutter/fml/macros.h"
21
22namespace flutter {
23
24// The primary class used to build a display list. The list of methods
25// here matches the list of methods invoked on a |DlOpReceiver| combined
26// with the list of methods invoked on a |DlCanvas|.
27class DisplayListBuilder final : public virtual DlCanvas,
28 public SkRefCnt,
29 virtual DlOpReceiver,
31 public:
32 static constexpr DlRect kMaxCullRect =
33 DlRect::MakeLTRB(-1E9F, -1E9F, 1E9F, 1E9F);
34
35 explicit DisplayListBuilder(bool prepare_rtree)
36 : DisplayListBuilder(kMaxCullRect, prepare_rtree) {}
37
38 explicit DisplayListBuilder(const DlRect& cull_rect = kMaxCullRect,
39 bool prepare_rtree = false);
40
43
45
46 // |DlCanvas|
47 DlISize GetBaseLayerDimensions() const override;
48 // |DlCanvas|
49 SkImageInfo GetImageInfo() const override;
50
51 // |DlCanvas|
52 void Save() override;
53
54 // |DlCanvas|
55 void SaveLayer(const std::optional<DlRect>& bounds,
56 const DlPaint* paint = nullptr,
57 const DlImageFilter* backdrop = nullptr,
58 std::optional<int64_t> backdrop_id = std::nullopt) override;
59 // |DlCanvas|
60 void Restore() override;
61 // |DlCanvas|
62 int GetSaveCount() const override { return save_stack_.size(); }
63 // |DlCanvas|
64 void RestoreToCount(int restore_count) override;
65
66 // |DlCanvas|
67 void Translate(DlScalar tx, DlScalar ty) override;
68 // |DlCanvas|
69 void Scale(DlScalar sx, DlScalar sy) override;
70 // |DlCanvas|
71 void Rotate(DlScalar degrees) override;
72 // |DlCanvas|
73 void Skew(DlScalar sx, DlScalar sy) override;
74
75 // clang-format off
76 // 2x3 2D affine subset of a 4x4 transform in row major order
77 // |DlCanvas|
79 DlScalar myx, DlScalar myy, DlScalar myt) override;
80 // full 4x4 transform in row major order
81 // |DlCanvas|
83 DlScalar mxx, DlScalar mxy, DlScalar mxz, DlScalar mxt,
84 DlScalar myx, DlScalar myy, DlScalar myz, DlScalar myt,
85 DlScalar mzx, DlScalar mzy, DlScalar mzz, DlScalar mzt,
86 DlScalar mwx, DlScalar mwy, DlScalar mwz, DlScalar mwt) override;
87 // clang-format on
88 // |DlCanvas|
89 void TransformReset() override;
90 // |DlCanvas|
91 void Transform(const DlMatrix& matrix) override;
92 // |DlCanvas|
93 void SetTransform(const DlMatrix& matrix) override {
95 Transform(matrix);
96 }
97
98 /// Returns the 4x4 full perspective transform representing all transform
99 /// operations executed so far in this DisplayList within the enclosing
100 /// save stack.
101 // |DlCanvas|
102 DlMatrix GetMatrix() const override { return global_state().matrix(); }
103
104 // |DlCanvas|
105 void ClipRect(const DlRect& rect,
107 bool is_aa = false) override;
108 // |DlCanvas|
109 void ClipOval(const DlRect& bounds,
111 bool is_aa = false) override;
112 // |DlCanvas|
113 void ClipRoundRect(const DlRoundRect& rrect,
115 bool is_aa = false) override;
116 // |DlCanvas|
119 bool is_aa = false) override;
120 // |DlCanvas|
121 void ClipPath(const DlPath& path,
123 bool is_aa = false) override;
124
125 /// Conservative estimate of the bounds of all outstanding clip operations
126 /// measured in the coordinate space within which this DisplayList will
127 /// be rendered.
128 // |DlCanvas|
130 return global_state().GetDeviceCullCoverage();
131 }
132 /// Conservative estimate of the bounds of all outstanding clip operations
133 /// transformed into the local coordinate space in which currently
134 /// recorded rendering operations are interpreted.
135 // |DlCanvas|
136 DlRect GetLocalClipCoverage() const override {
137 return global_state().GetLocalCullCoverage();
138 }
139
140 /// Return true iff the supplied bounds are easily shown to be outside
141 /// of the current clip bounds. This method may conservatively return
142 /// false if it cannot make the determination.
143 // |DlCanvas|
144 bool QuickReject(const DlRect& bounds) const override;
145
146 // |DlCanvas|
147 void DrawPaint(const DlPaint& paint) override;
148 // |DlCanvas|
149 void DrawColor(DlColor color, DlBlendMode mode) override;
150 // |DlCanvas|
151 void DrawLine(const DlPoint& p0,
152 const DlPoint& p1,
153 const DlPaint& paint) override;
154 // |DlCanvas|
155 void DrawDashedLine(const DlPoint& p0,
156 const DlPoint& p1,
157 DlScalar on_length,
158 DlScalar off_length,
159 const DlPaint& paint) override;
160 // |DlCanvas|
161 void DrawRect(const DlRect& rect, const DlPaint& paint) override;
162 // |DlCanvas|
163 void DrawOval(const DlRect& bounds, const DlPaint& paint) override;
164 // |DlCanvas|
165 void DrawCircle(const DlPoint& center,
166 DlScalar radius,
167 const DlPaint& paint) override;
168 // |DlCanvas|
169 void DrawRoundRect(const DlRoundRect& rrect, const DlPaint& paint) override;
170 // |DlCanvas|
171 void DrawDiffRoundRect(const DlRoundRect& outer,
172 const DlRoundRect& inner,
173 const DlPaint& paint) override;
174 // |DlCanvas|
176 const DlPaint& paint) override;
177 // |DlCanvas|
178 void DrawPath(const DlPath& path, const DlPaint& paint) override;
179 // |DlCanvas|
180 void DrawArc(const DlRect& bounds,
181 DlScalar start,
182 DlScalar sweep,
183 bool useCenter,
184 const DlPaint& paint) override;
185 // |DlCanvas|
186 void DrawPoints(DlPointMode mode,
187 uint32_t count,
188 const DlPoint pts[],
189 const DlPaint& paint) override;
190 // |DlCanvas|
191 void DrawVertices(const std::shared_ptr<DlVertices>& vertices,
192 DlBlendMode mode,
193 const DlPaint& paint) override;
194 // |DlCanvas|
195 void DrawImage(const sk_sp<DlImage>& image,
196 const DlPoint& point,
197 DlImageSampling sampling,
198 const DlPaint* paint = nullptr) override;
199 // |DlCanvas|
200 void DrawImageRect(
201 const sk_sp<DlImage>& image,
202 const DlRect& src,
203 const DlRect& dst,
204 DlImageSampling sampling,
205 const DlPaint* paint = nullptr,
206 DlSrcRectConstraint constraint = DlSrcRectConstraint::kFast) override;
207 // include overloads from the virtual base class
209
210 // |DlCanvas|
211 void DrawImageNine(const sk_sp<DlImage>& image,
212 const DlIRect& center,
213 const DlRect& dst,
214 DlFilterMode filter,
215 const DlPaint* paint = nullptr) override;
216 // |DlCanvas|
217 void DrawAtlas(const sk_sp<DlImage>& atlas,
218 const DlRSTransform xform[],
219 const DlRect tex[],
220 const DlColor colors[],
221 int count,
222 DlBlendMode mode,
223 DlImageSampling sampling,
224 const DlRect* cullRect,
225 const DlPaint* paint = nullptr) override;
226 // |DlCanvas|
227 void DrawDisplayList(const sk_sp<DisplayList> display_list,
228 DlScalar opacity = SK_Scalar1) override;
229 // |DlCanvas|
230 void DrawText(const std::shared_ptr<DlText>& text,
231 DlScalar x,
232 DlScalar y,
233 const DlPaint& paint) override;
234
235 // |DlCanvas|
236 void DrawShadow(const DlPath& path,
237 const DlColor color,
238 const DlScalar elevation,
239 bool transparent_occluder,
240 DlScalar dpr) override;
241
242 // |DlCanvas|
243 void Flush() override {}
244
245 sk_sp<DisplayList> Build();
246
247 private:
248 void Init(bool prepare_rtree);
249
250 // This method exposes the internal stateful DlOpReceiver implementation
251 // of the DisplayListBuilder, primarily for testing purposes. Its use
252 // is obsolete and forbidden in every other case and is only shared to a
253 // pair of "friend" accessors in the benchmark/unittest files.
254 DlOpReceiver& asReceiver() { return *this; }
255
256 friend DlOpReceiver& DisplayListBuilderBenchmarkAccessor(
257 DisplayListBuilder& builder);
258 friend DlOpReceiver& DisplayListBuilderTestingAccessor(
259 DisplayListBuilder& builder);
261 DisplayListBuilder& builder);
262 friend int DisplayListBuilderTestingLastOpIndex(DisplayListBuilder& builder);
263
264 void SetAttributesFromPaint(const DlPaint& paint,
265 const DisplayListAttributeFlags flags);
266
267 // |DlOpReceiver|
268 void setAntiAlias(bool aa) override {
269 if (current_.isAntiAlias() != aa) {
270 onSetAntiAlias(aa);
271 }
272 }
273 // |DlOpReceiver|
274 void setInvertColors(bool invert) override {
275 if (current_.isInvertColors() != invert) {
276 onSetInvertColors(invert);
277 }
278 }
279 // |DlOpReceiver|
280 void setStrokeCap(DlStrokeCap cap) override {
281 if (current_.getStrokeCap() != cap) {
282 onSetStrokeCap(cap);
283 }
284 }
285 // |DlOpReceiver|
286 void setStrokeJoin(DlStrokeJoin join) override {
287 if (current_.getStrokeJoin() != join) {
288 onSetStrokeJoin(join);
289 }
290 }
291 // |DlOpReceiver|
292 void setDrawStyle(DlDrawStyle style) override {
293 if (current_.getDrawStyle() != style) {
294 onSetDrawStyle(style);
295 }
296 }
297 // |DlOpReceiver|
298 void setStrokeWidth(float width) override {
299 if (current_.getStrokeWidth() != width) {
300 onSetStrokeWidth(width);
301 }
302 }
303 // |DlOpReceiver|
304 void setStrokeMiter(float limit) override {
305 if (current_.getStrokeMiter() != limit) {
306 onSetStrokeMiter(limit);
307 }
308 }
309 // |DlOpReceiver|
310 void setColor(DlColor color) override {
311 if (current_.getColor() != color) {
312 onSetColor(color);
313 }
314 }
315 // |DlOpReceiver|
316 void setBlendMode(DlBlendMode mode) override {
317 if (current_.getBlendMode() != mode) {
318 onSetBlendMode(mode);
319 }
320 }
321 // |DlOpReceiver|
322 void setColorSource(const DlColorSource* source) override {
323 if (NotEquals(current_.getColorSourcePtr(), source)) {
324 onSetColorSource(source);
325 }
326 }
327 // |DlOpReceiver|
328 void setImageFilter(const DlImageFilter* filter) override {
329 if (NotEquals(current_.getImageFilterPtr(), filter)) {
330 onSetImageFilter(filter);
331 }
332 }
333 // |DlOpReceiver|
334 void setColorFilter(const DlColorFilter* filter) override {
335 if (NotEquals(current_.getColorFilterPtr(), filter)) {
336 onSetColorFilter(filter);
337 }
338 }
339 // |DlOpReceiver|
340 void setMaskFilter(const DlMaskFilter* filter) override {
341 if (NotEquals(current_.getMaskFilterPtr(), filter)) {
342 onSetMaskFilter(filter);
343 }
344 }
345
346 DlPaint CurrentAttributes() const { return current_; }
347 int LastOpIndex() const { return op_index_ - 1; }
348
349 // |DlOpReceiver|
350 void save() override { Save(); }
351 // Only the |renders_with_attributes()| option will be accepted here. Any
352 // other flags will be ignored and calculated anew as the DisplayList is
353 // built. Alternatively, use the |saveLayer(DlRect, bool)| method.
354 // |DlOpReceiver|
355 void saveLayer(const DlRect& bounds,
356 const SaveLayerOptions options,
357 const DlImageFilter* backdrop,
358 std::optional<int64_t> backdrop_id) override;
359 // |DlOpReceiver|
360 void restore() override { Restore(); }
361
362 // |DlOpReceiver|
363 void translate(DlScalar tx, DlScalar ty) override { Translate(tx, ty); }
364 // |DlOpReceiver|
365 void scale(DlScalar sx, DlScalar sy) override { Scale(sx, sy); }
366 // |DlOpReceiver|
367 void rotate(DlScalar degrees) override { Rotate(degrees); }
368 // |DlOpReceiver|
369 void skew(DlScalar sx, DlScalar sy) override { Skew(sx, sy); }
370
371 // clang-format off
372 // |DlOpReceiver|
373 void transform2DAffine(DlScalar mxx, DlScalar mxy, DlScalar mxt,
374 DlScalar myx, DlScalar myy, DlScalar myt) override {
375 Transform2DAffine(mxx, mxy, mxt, myx, myy, myt);
376 }
377 // |DlOpReceiver|
378 void transformFullPerspective(
379 DlScalar mxx, DlScalar mxy, DlScalar mxz, DlScalar mxt,
380 DlScalar myx, DlScalar myy, DlScalar myz, DlScalar myt,
381 DlScalar mzx, DlScalar mzy, DlScalar mzz, DlScalar mzt,
382 DlScalar mwx, DlScalar mwy, DlScalar mwz, DlScalar mwt) override {
383 TransformFullPerspective(mxx, mxy, mxz, mxt,
384 myx, myy, myz, myt,
385 mzx, mzy, mzz, mzt,
386 mwx, mwy, mwz, mwt);
387 }
388 // clang-format off
389 // |DlOpReceiver|
390 void transformReset() override { TransformReset(); }
391
392 // |DlOpReceiver|
393 void clipRect(const DlRect& rect, DlClipOp clip_op, bool is_aa) override {
394 ClipRect(rect, clip_op, is_aa);
395 }
396 // |DlOpReceiver|
397 void clipOval(const DlRect& bounds, DlClipOp clip_op, bool is_aa) override {
398 ClipOval(bounds, clip_op, is_aa);
399 }
400 // |DlOpReceiver|
401 void clipRoundRect(const DlRoundRect& rrect,
402 DlClipOp clip_op,
403 bool is_aa) override {
404 ClipRoundRect(rrect, clip_op, is_aa);
405 }
406 // |DlOpReceiver|
407 void clipRoundSuperellipse(const DlRoundSuperellipse& rse,
408 DlClipOp clip_op,
409 bool is_aa) override {
410 ClipRoundSuperellipse(rse, clip_op, is_aa);
411 }
412 // |DlOpReceiver|
413 void clipPath(const DlPath& path, DlClipOp clip_op, bool is_aa) override {
414 ClipPath(path, clip_op, is_aa);
415 }
416
417 // |DlOpReceiver|
418 void drawPaint() override;
419 // |DlOpReceiver|
420 void drawColor(DlColor color, DlBlendMode mode) override {
421 DrawColor(color, mode);
422 }
423 // |DlOpReceiver|
424 void drawLine(const DlPoint& p0, const DlPoint& p1) override;
425 // |DlOpReceiver|
426 void drawDashedLine(const DlPoint& p0,
427 const DlPoint& p1,
428 DlScalar on_length,
429 DlScalar off_length) override;
430 // |DlOpReceiver|
431 void drawRect(const DlRect& rect) override;
432 // |DlOpReceiver|
433 void drawOval(const DlRect& bounds) override;
434 // |DlOpReceiver|
435 void drawCircle(const DlPoint& center, DlScalar radius) override;
436 // |DlOpReceiver|
437 void drawRoundRect(const DlRoundRect& rrect) override;
438 // |DlOpReceiver|
439 void drawDiffRoundRect(const DlRoundRect& outer,
440 const DlRoundRect& inner) override;
441 // |DlOpReceiver|
442 void drawRoundSuperellipse(const DlRoundSuperellipse& rse) override;
443 // |DlOpReceiver|
444 void drawPath(const DlPath& path) override;
445 // |DlOpReceiver|
446 void drawArc(const DlRect& bounds,
447 DlScalar start,
448 DlScalar sweep,
449 bool useCenter) override;
450 // |DlOpReceiver|
451 void drawPoints(DlPointMode mode, uint32_t count, const DlPoint pts[]) override;
452 // |DlOpReceiver|
453 void drawVertices(const std::shared_ptr<DlVertices>& vertices,
454 DlBlendMode mode) override;
455
456 // |DlOpReceiver|
457 void drawImage(const sk_sp<DlImage> image,
458 const DlPoint& point,
459 DlImageSampling sampling,
460 bool render_with_attributes) override;
461 // |DlOpReceiver|
462 void drawImageRect(
463 const sk_sp<DlImage> image,
464 const DlRect& src,
465 const DlRect& dst,
466 DlImageSampling sampling,
467 bool render_with_attributes,
468 DlSrcRectConstraint constraint = DlSrcRectConstraint::kFast) override;
469 // |DlOpReceiver|
470 void drawImageNine(const sk_sp<DlImage> image,
471 const DlIRect& center,
472 const DlRect& dst,
473 DlFilterMode filter,
474 bool render_with_attributes) override;
475 // |DlOpReceiver|
476 void drawAtlas(const sk_sp<DlImage> atlas,
477 const DlRSTransform xform[],
478 const DlRect tex[],
479 const DlColor colors[],
480 int count,
481 DlBlendMode mode,
482 DlImageSampling sampling,
483 const DlRect* cullRect,
484 bool render_with_attributes) override;
485
486 // |DlOpReceiver|
487 void drawDisplayList(const sk_sp<DisplayList> display_list,
488 DlScalar opacity) override {
489 DrawDisplayList(display_list, opacity);
490 }
491
492 // |DlOpReceiver|
493 void drawText(const std::shared_ptr<DlText>& text,
494 DlScalar x,
495 DlScalar y) override;
496
497 // |DlOpReceiver|
498 void drawShadow(const DlPath& path,
499 const DlColor color,
500 const DlScalar elevation,
501 bool transparent_occluder,
502 DlScalar dpr) override {
503 DrawShadow(path, color, elevation, transparent_occluder, dpr);
504 }
505
506 void checkForDeferredSave();
507
508 DisplayListStorage storage_;
509 std::vector<size_t> offsets_;
510 uint32_t render_op_count_ = 0u;
511 uint32_t depth_ = 0u;
512 // Most rendering ops will use 1 depth value, but some attributes may
513 // require an additional depth value (due to implicit saveLayers)
514 uint32_t render_op_depth_cost_ = 1u;
515 DlIndex op_index_ = 0;
516
517 // bytes and ops from |drawPicture| and |drawDisplayList|
518 size_t nested_bytes_ = 0;
519 uint32_t nested_op_count_ = 0;
520
521 bool is_ui_thread_safe_ = true;
522
523 template <typename T, typename... Args>
524 void* Push(size_t extra, Args&&... args);
525
526 struct RTreeData {
527 std::vector<DlRect> rects;
528 std::vector<int> indices;
529 };
530
531 struct LayerInfo {
532 LayerInfo(const std::shared_ptr<DlImageFilter>& filter,
533 size_t rtree_rects_start_index)
534 : filter(filter),
535 rtree_rects_start_index(rtree_rects_start_index) {}
536
537 // The filter that will be applied to the contents of the saveLayer
538 // when it is restored into the parent layer.
539 const std::shared_ptr<DlImageFilter> filter;
540
541 // The index of the rtree rects when the saveLayer was called, used
542 // only in the case that the saveLayer has a filter so that the
543 // accumulated rects can be updated in the corresponding restore call.
544 const size_t rtree_rects_start_index = 0;
545
546 // The bounds accumulator for the entire DisplayList, relative to its root
547 // (not used when accumulating rects for an rtree, though)
548 AccumulationRect global_space_accumulator;
549
550 // The bounds accumulator to set/verify the bounds of the most recently
551 // invoked saveLayer call, relative to the root of that saveLayer
552 AccumulationRect layer_local_accumulator;
553
554 DlBlendMode max_blend_mode = DlBlendMode::kClear;
555
556 bool opacity_incompatible_op_detected = false;
557 bool affects_transparent_layer = false;
558 bool contains_backdrop_filter = false;
559 bool is_unbounded = false;
560
561 bool is_group_opacity_compatible() const {
562 return !opacity_incompatible_op_detected &&
563 !layer_local_accumulator.overlap_detected();
564 }
565
566 void update_blend_mode(DlBlendMode mode) {
567 if (max_blend_mode < mode) {
568 max_blend_mode = mode;
569 }
570 }
571 };
572
573 // The SaveInfo class stores internal data common to both Save and
574 // SaveLayer calls
575 class SaveInfo {
576 public:
577 // For vector reallocation calls to copy vector data
578 SaveInfo(const SaveInfo& copy) = default;
579 SaveInfo(SaveInfo&& copy) = default;
580
581 // For constructor (root layer) initialization
582 explicit SaveInfo(const DlRect& cull_rect)
583 : is_save_layer(true),
584 has_valid_clip(false),
585 global_state(cull_rect),
586 layer_state(cull_rect),
587 layer_info(new LayerInfo(nullptr, 0u)) {}
588
589 // For regular save calls:
590 // Passing a pointer to the parent_info so as to distinguish this
591 // call from the copy constructors used during vector reallocations
592 explicit SaveInfo(const SaveInfo* parent_info)
593 : is_save_layer(false),
594 has_deferred_save_op(true),
595 has_valid_clip(parent_info->has_valid_clip),
596 global_state(parent_info->global_state),
597 layer_state(parent_info->layer_state),
598 layer_info(parent_info->layer_info) {}
599
600 // For saveLayer calls:
601 explicit SaveInfo(const SaveInfo* parent_info,
602 const std::shared_ptr<DlImageFilter>& filter,
603 int rtree_rect_index)
604 : is_save_layer(true),
605 has_valid_clip(false),
606 global_state(parent_info->global_state),
607 layer_state(kMaxCullRect),
608 layer_info(new LayerInfo(filter, rtree_rect_index)) {}
609
610 const bool is_save_layer;
611
612 bool has_deferred_save_op = false;
613 bool is_nop = false;
614 bool has_valid_clip;
615
616 // The depth when the save call is recorded, used to compute the total
617 // depth of its content when the associated restore is called.
618 uint32_t save_depth = 0;
619
620 // The offset into the buffer where the associated save op is recorded
621 // (which is not necessarily the same as when the Save() method is called
622 // due to deferred saves)
623 size_t save_offset = 0;
624
625 // The transform and clip accumulated since the root of the DisplayList
626 DisplayListMatrixClipState global_state;
627
628 // The transform and clip accumulated since the most recent saveLayer,
629 // used to compute and update its bounds when the restore is called.
630 DisplayListMatrixClipState layer_state;
631
632 std::shared_ptr<LayerInfo> layer_info;
633
634 // Records the given bounds after transforming by the global and
635 // layer matrices.
636 bool AccumulateBoundsLocal(const DlRect& bounds);
637
638 // Simply transfers the local bounds to the parent
639 void TransferBoundsToParent(const SaveInfo& parent);
640 };
641
642 const DlRect original_cull_rect_;
643 std::vector<SaveInfo> save_stack_;
644 std::optional<RTreeData> rtree_data_;
645
646 DlPaint current_;
647
648 // Returns a reference to the SaveInfo structure at the top of the current
649 // save_stack vector. Note that the clip and matrix state can be accessed
650 // more directly through global_state() and layer_state().
651 SaveInfo& current_info() { return save_stack_.back(); }
652 const SaveInfo& current_info() const { return save_stack_.back(); }
653
654 // Returns a reference to the SaveInfo structure just below the top
655 // of the current save_stack state.
656 SaveInfo& parent_info() { return *std::prev(save_stack_.end(), 2); }
657 const SaveInfo& parent_info() const {
658 return *std::prev(save_stack_.end(), 2);
659 }
660
661 // Returns a reference to the LayerInfo structure at the top of the current
662 // save_stack vector. Note that the clip and matrix state can be accessed
663 // more directly through global_state() and layer_state().
664 LayerInfo& current_layer() { return *save_stack_.back().layer_info; }
665 const LayerInfo& current_layer() const {
666 return *save_stack_.back().layer_info;
667 }
668
669 // Returns a reference to the LayerInfo structure just below the top
670 // of the current save_stack state.
671 LayerInfo& parent_layer() {
672 return *std::prev(save_stack_.end(), 2)->layer_info;
673 }
674 const LayerInfo& parent_layer() const {
675 return *std::prev(save_stack_.end(), 2)->layer_info;
676 }
677
678 // Returns a reference to the matrix and clip state for the entire
679 // DisplayList. The initial transform of this state is identity and
680 // the initial cull_rect is the root original_cull_rect supplied
681 // in the constructor. It is a summary of all transform and clip
682 // calls that have happened since the DisplayList was created
683 // (and have not yet been removed by a restore() call).
684 DisplayListMatrixClipState& global_state() {
685 return current_info().global_state;
686 }
687 const DisplayListMatrixClipState& global_state() const {
688 return current_info().global_state;
689 }
690
691 // Returns a reference to the matrix and clip state relative to the
692 // current layer, whether that is defined by the most recent saveLayer
693 // call, or by the initial root state of the entire DisplayList for
694 // calls not surrounded by a saveLayer/restore pair. It is a summary
695 // of only those transform and clip calls that have happened since
696 // the creation of the DisplayList or since the most recent saveLayer
697 // (and have not yet been removed by a restore() call).
698 DisplayListMatrixClipState& layer_local_state() {
699 return current_info().layer_state;
700 }
701 const DisplayListMatrixClipState& layer_local_state() const {
702 return current_info().layer_state;
703 }
704
705 void RestoreLayer();
706 void TransferLayerBounds(const DlRect& content_bounds);
707 bool AdjustRTreeRects(RTreeData& data,
708 const DlImageFilter& filter,
709 const DlMatrix& matrix,
710 const DlRect& clip,
711 size_t rect_index);
712
713 // This flag indicates whether or not the current rendering attributes
714 // are compatible with rendering ops applying an inherited opacity.
715 bool current_opacity_compatibility_ = true;
716
717 // Returns the compatibility of a given blend mode for applying an
718 // inherited opacity value to modulate the visibility of the op.
719 // For now we only accept SrcOver blend modes but this could be expanded
720 // in the future to include other (rarely used) modes that also modulate
721 // the opacity of a rendering operation at the cost of a switch statement
722 // or lookup table.
723 static bool IsOpacityCompatible(DlBlendMode mode) {
724 return (mode == DlBlendMode::kSrcOver);
725 }
726
727 void UpdateCurrentOpacityCompatibility() {
728 current_opacity_compatibility_ = //
729 current_.getColorFilter() == nullptr && //
730 !current_.isInvertColors() && //
731 !current_.usesRuntimeEffect() && //
732 IsOpacityCompatible(current_.getBlendMode());
733 }
734
735 // Update the opacity compatibility flags of the current layer for an op
736 // that has determined its compatibility as indicated by |compatible|.
737 void UpdateLayerOpacityCompatibility(bool compatible) {
738 if (!compatible) {
739 current_layer().opacity_incompatible_op_detected = true;
740 }
741 }
742
743 // Check for opacity compatibility for an op that may or may not use the
744 // current rendering attributes as indicated by |uses_blend_attribute|.
745 // If the flag is false then the rendering op will be able to substitute
746 // a default Paint object with the opacity applied using the default SrcOver
747 // blend mode which is always compatible with applying an inherited opacity.
748 void CheckLayerOpacityCompatibility(bool uses_blend_attribute = true) {
749 UpdateLayerOpacityCompatibility(!uses_blend_attribute ||
750 current_opacity_compatibility_);
751 }
752
753 void CheckLayerOpacityHairlineCompatibility() {
754 UpdateLayerOpacityCompatibility(
755 current_opacity_compatibility_ &&
756 (current_.getDrawStyle() == DlDrawStyle::kFill ||
757 current_.getStrokeWidth() > 0));
758 }
759
760 // Check for opacity compatibility for an op that ignores the current
761 // attributes and uses the indicated blend |mode| to render to the layer.
762 // This is only used by |drawColor| currently.
763 void CheckLayerOpacityCompatibility(DlBlendMode mode) {
764 UpdateLayerOpacityCompatibility(IsOpacityCompatible(mode));
765 }
766
767 void onSetAntiAlias(bool aa);
768 void onSetInvertColors(bool invert);
769 void onSetStrokeCap(DlStrokeCap cap);
770 void onSetStrokeJoin(DlStrokeJoin join);
771 void onSetDrawStyle(DlDrawStyle style);
772 void onSetStrokeWidth(DlScalar width);
773 void onSetStrokeMiter(DlScalar limit);
774 void onSetColor(DlColor color);
775 void onSetBlendMode(DlBlendMode mode);
776 void onSetColorSource(const DlColorSource* source);
777 void onSetImageFilter(const DlImageFilter* filter);
778 void onSetColorFilter(const DlColorFilter* filter);
779 void onSetMaskFilter(const DlMaskFilter* filter);
780
781 static DisplayListAttributeFlags FlagsForPointMode(DlPointMode mode);
782
783 enum class OpResult {
784 kNoEffect,
785 kPreservesTransparency,
786 kAffectsAll,
787 };
788
789 bool paint_nops_on_transparency();
790 OpResult PaintResult(const DlPaint& paint,
791 DisplayListAttributeFlags flags = kDrawPaintFlags);
792
793 void UpdateLayerResult(OpResult result, DlBlendMode mode) {
794 switch (result) {
795 case OpResult::kNoEffect:
796 case OpResult::kPreservesTransparency:
797 break;
798 case OpResult::kAffectsAll:
799 current_layer().affects_transparent_layer = true;
800 break;
801 }
802 current_layer().update_blend_mode(mode);
803 }
804 void UpdateLayerResult(OpResult result, bool uses_attributes = true) {
805 UpdateLayerResult(result, uses_attributes ? current_.getBlendMode()
807 }
808
809 // kAnyColor is a non-opaque and non-transparent color that will not
810 // trigger any short-circuit tests about the results of a blend.
811 static constexpr DlColor kAnyColor = DlColor::kMidGrey().withAlphaF(0.5f);
812 static_assert(!kAnyColor.isOpaque());
813 static_assert(!kAnyColor.isTransparent());
814 static DlColor GetEffectiveColor(const DlPaint& paint,
815 DisplayListAttributeFlags flags);
816
817 // Adjusts the indicated bounds for the given flags and returns true if
818 // the calculation was possible, or false if it could not be estimated.
819 bool AdjustBoundsForPaint(DlRect& bounds, DisplayListAttributeFlags flags);
820
821 // Records the fact that we encountered an op that either could not
822 // estimate its bounds or that fills all of the destination space.
823 bool AccumulateUnbounded(const SaveInfo& save);
824 bool AccumulateUnbounded() {
825 return AccumulateUnbounded(current_info());
826 }
827
828 // Records the bounds for an op after modifying them according to the
829 // supplied attribute flags and transforming by the current matrix.
830 bool AccumulateOpBounds(const DlRect& bounds,
831 DisplayListAttributeFlags flags) {
832 DlRect safe_bounds = bounds;
833 return AccumulateOpBounds(safe_bounds, flags);
834 }
835
836 // Records the bounds for an op after modifying them according to the
837 // supplied attribute flags and transforming by the current matrix
838 // and clipping against the current clip.
839 bool AccumulateOpBounds(DlRect& bounds, DisplayListAttributeFlags flags);
840
841 // Records the given bounds after transforming by the current matrix
842 // and clipping against the current clip.
843 bool AccumulateBounds(const DlRect& bounds, SaveInfo& layer, int id);
844 bool AccumulateBounds(const DlRect& bounds) {
845 return AccumulateBounds(bounds, current_info(), op_index_);
846 }
847};
848
849} // namespace flutter
850
851#endif // FLUTTER_DISPLAY_LIST_DL_BUILDER_H_
void DrawOval(const DlRect &bounds, const DlPaint &paint) override
static constexpr DlRect kMaxCullRect
Definition dl_builder.h:32
friend DlOpReceiver & DisplayListBuilderBenchmarkAccessor(DisplayListBuilder &builder)
void ClipRect(const DlRect &rect, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false) override
void DrawImageRect(const sk_sp< DlImage > &image, const DlRect &src, const DlRect &dst, DlImageSampling sampling, const DlPaint *paint=nullptr, DlSrcRectConstraint constraint=DlSrcRectConstraint::kFast) override
void DrawVertices(const std::shared_ptr< DlVertices > &vertices, DlBlendMode mode, const DlPaint &paint) override
void DrawImageNine(const sk_sp< DlImage > &image, const DlIRect &center, const DlRect &dst, DlFilterMode filter, const DlPaint *paint=nullptr) override
void DrawAtlas(const sk_sp< DlImage > &atlas, const DlRSTransform xform[], const DlRect tex[], const DlColor colors[], int count, DlBlendMode mode, DlImageSampling sampling, const DlRect *cullRect, const DlPaint *paint=nullptr) override
void DrawRoundRect(const DlRoundRect &rrect, const DlPaint &paint) override
void RestoreToCount(int restore_count) override
void DrawArc(const DlRect &bounds, DlScalar start, DlScalar sweep, bool useCenter, const DlPaint &paint) override
void DrawShadow(const DlPath &path, const DlColor color, const DlScalar elevation, bool transparent_occluder, DlScalar dpr) override
Draws the shadow of the given |path| rendered in the provided |color| (which is only consulted for it...
void DrawImage(const sk_sp< DlImage > &image, const DlPoint &point, DlImageSampling sampling, const DlPaint *paint=nullptr) override
void DrawColor(DlColor color, DlBlendMode mode) override
void SetTransform(const DlMatrix &matrix) override
Definition dl_builder.h:93
DlMatrix GetMatrix() const override
Definition dl_builder.h:102
void DrawCircle(const DlPoint &center, DlScalar radius, const DlPaint &paint) override
void TransformReset() override
friend DlOpReceiver & DisplayListBuilderTestingAccessor(DisplayListBuilder &builder)
void SaveLayer(const std::optional< DlRect > &bounds, const DlPaint *paint=nullptr, const DlImageFilter *backdrop=nullptr, std::optional< int64_t > backdrop_id=std::nullopt) override
void ClipRoundSuperellipse(const DlRoundSuperellipse &rse, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false) override
void DrawLine(const DlPoint &p0, const DlPoint &p1, const DlPaint &paint) override
DlISize GetBaseLayerDimensions() const override
void ClipRoundRect(const DlRoundRect &rrect, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false) override
void Rotate(DlScalar degrees) override
DisplayListBuilder(bool prepare_rtree)
Definition dl_builder.h:35
void DrawRoundSuperellipse(const DlRoundSuperellipse &rse, const DlPaint &paint) override
void Scale(DlScalar sx, DlScalar sy) override
void DrawDisplayList(const sk_sp< DisplayList > display_list, DlScalar opacity=SK_Scalar1) override
friend int DisplayListBuilderTestingLastOpIndex(DisplayListBuilder &builder)
SkImageInfo GetImageInfo() const override
void Skew(DlScalar sx, DlScalar sy) override
void Translate(DlScalar tx, DlScalar ty) override
void Transform2DAffine(DlScalar mxx, DlScalar mxy, DlScalar mxt, DlScalar myx, DlScalar myy, DlScalar myt) override
void DrawPaint(const DlPaint &paint) override
DisplayListBuilder(DlScalar width, DlScalar height)
Definition dl_builder.h:41
void DrawDashedLine(const DlPoint &p0, const DlPoint &p1, DlScalar on_length, DlScalar off_length, const DlPaint &paint) override
sk_sp< DisplayList > Build()
Definition dl_builder.cc:66
void DrawPath(const DlPath &path, const DlPaint &paint) override
bool QuickReject(const DlRect &bounds) const override
DlRect GetDestinationClipCoverage() const override
Definition dl_builder.h:129
friend DlPaint DisplayListBuilderTestingAttributes(DisplayListBuilder &builder)
void ClipPath(const DlPath &path, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false) override
void DrawPoints(DlPointMode mode, uint32_t count, const DlPoint pts[], const DlPaint &paint) override
void ClipOval(const DlRect &bounds, DlClipOp clip_op=DlClipOp::kIntersect, bool is_aa=false) override
DlRect GetLocalClipCoverage() const override
Definition dl_builder.h:136
int GetSaveCount() const override
Definition dl_builder.h:62
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 DrawDiffRoundRect(const DlRoundRect &outer, const DlRoundRect &inner, const DlPaint &paint) override
void Transform(const DlMatrix &matrix) override
void DrawRect(const DlRect &rect, const DlPaint &paint) override
static constexpr DisplayListAttributeFlags kDrawPaintFlags
Developer-facing API for rendering anything within the engine.
Definition dl_canvas.h:32
virtual void DrawImageRect(const sk_sp< DlImage > &image, const DlRect &src, const DlRect &dst, DlImageSampling sampling, const DlPaint *paint=nullptr, DlSrcRectConstraint constraint=DlSrcRectConstraint::kFast)=0
Internal API for rendering recorded display lists to backends.
bool isAntiAlias() const
Definition dl_paint.h:57
DlStrokeCap getStrokeCap() const
Definition dl_paint.h:98
DlColor getColor() const
Definition dl_paint.h:69
DlBlendMode getBlendMode() const
Definition dl_paint.h:82
float getStrokeMiter() const
Definition dl_paint.h:120
DlStrokeJoin getStrokeJoin() const
Definition dl_paint.h:106
const DlColorSource * getColorSourcePtr() const
Definition dl_paint.h:129
const DlMaskFilter * getMaskFilterPtr() const
Definition dl_paint.h:183
const DlColorFilter * getColorFilterPtr() const
Definition dl_paint.h:147
const DlImageFilter * getImageFilterPtr() const
Definition dl_paint.h:165
DlDrawStyle getDrawStyle() const
Definition dl_paint.h:90
float getStrokeWidth() const
Definition dl_paint.h:114
bool isInvertColors() const
Definition dl_paint.h:63
int32_t x
FlutterVulkanImage * image
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
std::u16string text
double y
impeller::Scalar DlScalar
uint32_t DlIndex
DlStrokeJoin
Definition dl_paint.h:37
impeller::RoundRect DlRoundRect
DlStrokeCap
Definition dl_paint.h:28
impeller::RSTransform DlRSTransform
impeller::Matrix DlMatrix
impeller::Rect DlRect
impeller::RoundSuperellipse DlRoundSuperellipse
DlPointMode
Definition dl_types.h:15
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition switch_defs.h:52
DlDrawStyle
Definition dl_paint.h:19
@ kFill
fills interior of shapes
impeller::IRect32 DlIRect
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
Definition switch_defs.h:36
it will be possible to load the file into Perfetto s trace viewer use test Running tests that layout and measure text will not yield consistent results across various platforms Enabling this option will make font resolution default to the Ahem test font on all disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
impeller::BlendMode DlBlendMode
bool NotEquals(const T *a, const U *b)
impeller::Point DlPoint
DlSrcRectConstraint
Definition dl_types.h:21
BlendMode
Definition color.h:58
flutter::DlColor DlColor
flutter::DlPaint DlPaint
int32_t height
int32_t width
static constexpr DlColor kMidGrey()
Definition dl_color.h:78
constexpr DlColor withAlphaF(float alpha) const
Definition dl_color.h:132
A 4x4 matrix using column-major storage.
Definition matrix.h:37
static constexpr TRect MakeLTRB(Type left, Type top, Type right, Type bottom)
Definition rect.h:129
#define DrawText