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