Skip to content

Commit db46fcc

Browse files
ColdPaleLightloic-sharma
authored andcommitted
Use DisplayListMatrixClipTracker in DisplayListBuilder (flutter#38349)
* Use DisplayListMatrixClipTracker in DisplayListBuilder * Ignore is_aa * Revert "Ignore is_aa" This reverts commit b201dad. * Tweak code * Use content_culled * getLocalClipBounds without device clip bounds roundsOut * Tweak code and add more tests * remove virtual
1 parent 3e7f69f commit db46fcc

7 files changed

+526
-163
lines changed

display_list/display_list_builder.cc

Lines changed: 30 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,15 @@ sk_sp<DisplayList> DisplayListBuilder::Build() {
6767
}
6868

6969
DisplayListBuilder::DisplayListBuilder(const SkRect& cull_rect,
70-
bool prepare_rtree) {
70+
bool prepare_rtree)
71+
: tracker_(cull_rect, SkMatrix::I()) {
7172
if (prepare_rtree) {
7273
accumulator_ = std::make_unique<RTreeBoundsAccumulator>();
7374
} else {
7475
accumulator_ = std::make_unique<RectBoundsAccumulator>();
7576
}
7677

77-
// isEmpty protects us against NaN as we normalize any empty cull rects
78-
SkRect cull = cull_rect.isEmpty() ? SkRect::MakeEmpty() : cull_rect;
79-
layer_stack_.emplace_back(SkM44(), SkMatrix::I(), cull);
78+
layer_stack_.emplace_back();
8079
current_layer_ = &layer_stack_.back();
8180
}
8281

@@ -440,9 +439,10 @@ void DisplayListBuilder::checkForDeferredSave() {
440439
}
441440

442441
void DisplayListBuilder::save() {
443-
layer_stack_.emplace_back(current_layer_);
442+
layer_stack_.emplace_back();
444443
current_layer_ = &layer_stack_.back();
445444
current_layer_->has_deferred_save_op_ = true;
445+
tracker_.save();
446446
accumulator()->save();
447447
}
448448

@@ -455,6 +455,7 @@ void DisplayListBuilder::restore() {
455455
// on the stack.
456456
LayerInfo layer_info = layer_stack_.back();
457457

458+
tracker_.restore();
458459
layer_stack_.pop_back();
459460
current_layer_ = &layer_stack_.back();
460461
bool is_unbounded = layer_info.is_unbounded();
@@ -463,7 +464,7 @@ void DisplayListBuilder::restore() {
463464
// current accumulator and adjust it as required based on the filter.
464465
std::shared_ptr<const DlImageFilter> filter = layer_info.filter();
465466
if (filter) {
466-
const SkRect* clip = &current_layer_->clip_bounds();
467+
const SkRect clip = tracker_.device_cull_rect();
467468
if (!accumulator()->restore(
468469
[filter = filter, matrix = getTransform()](const SkRect& input,
469470
SkRect& output) {
@@ -473,7 +474,7 @@ void DisplayListBuilder::restore() {
473474
output.set(output_bounds);
474475
return ret;
475476
},
476-
clip)) {
477+
&clip)) {
477478
is_unbounded = true;
478479
}
479480
} else {
@@ -544,11 +545,12 @@ void DisplayListBuilder::saveLayer(const SkRect* bounds,
544545
// We will fill the clip of the outer layer when we restore
545546
AccumulateUnbounded();
546547
}
547-
layer_stack_.emplace_back(current_layer_, save_layer_offset, true,
548+
layer_stack_.emplace_back(save_layer_offset, true,
548549
current_.getImageFilter());
549550
} else {
550-
layer_stack_.emplace_back(current_layer_, save_layer_offset, true, nullptr);
551+
layer_stack_.emplace_back(save_layer_offset, true, nullptr);
551552
}
553+
tracker_.save();
552554
accumulator()->save();
553555
current_layer_ = &layer_stack_.back();
554556
if (options.renders_with_attributes()) {
@@ -566,7 +568,7 @@ void DisplayListBuilder::saveLayer(const SkRect* bounds,
566568
// use them as the temporary layer bounds during rendering the layer, so
567569
// we set them as if a clip operation were performed.
568570
if (bounds) {
569-
intersect(*bounds);
571+
tracker_.clipRect(*bounds, SkClipOp::kIntersect, false);
570572
}
571573
if (backdrop) {
572574
// A backdrop will affect up to the entire surface, bounded by the clip
@@ -590,34 +592,30 @@ void DisplayListBuilder::translate(SkScalar tx, SkScalar ty) {
590592
(tx != 0.0 || ty != 0.0)) {
591593
checkForDeferredSave();
592594
Push<TranslateOp>(0, 1, tx, ty);
593-
current_layer_->matrix().preTranslate(tx, ty);
594-
current_layer_->update_matrix33();
595+
tracker_.translate(tx, ty);
595596
}
596597
}
597598
void DisplayListBuilder::scale(SkScalar sx, SkScalar sy) {
598599
if (SkScalarIsFinite(sx) && SkScalarIsFinite(sy) &&
599600
(sx != 1.0 || sy != 1.0)) {
600601
checkForDeferredSave();
601602
Push<ScaleOp>(0, 1, sx, sy);
602-
current_layer_->matrix().preScale(sx, sy);
603-
current_layer_->update_matrix33();
603+
tracker_.scale(sx, sy);
604604
}
605605
}
606606
void DisplayListBuilder::rotate(SkScalar degrees) {
607607
if (SkScalarMod(degrees, 360.0) != 0.0) {
608608
checkForDeferredSave();
609609
Push<RotateOp>(0, 1, degrees);
610-
current_layer_->matrix().preConcat(SkMatrix::RotateDeg(degrees));
611-
current_layer_->update_matrix33();
610+
tracker_.rotate(degrees);
612611
}
613612
}
614613
void DisplayListBuilder::skew(SkScalar sx, SkScalar sy) {
615614
if (SkScalarIsFinite(sx) && SkScalarIsFinite(sy) &&
616615
(sx != 0.0 || sy != 0.0)) {
617616
checkForDeferredSave();
618617
Push<SkewOp>(0, 1, sx, sy);
619-
current_layer_->matrix().preConcat(SkMatrix::Skew(sx, sy));
620-
current_layer_->update_matrix33();
618+
tracker_.skew(sx, sy);
621619
}
622620
}
623621

@@ -636,11 +634,8 @@ void DisplayListBuilder::transform2DAffine(
636634
Push<Transform2DAffineOp>(0, 1,
637635
mxx, mxy, mxt,
638636
myx, myy, myt);
639-
current_layer_->matrix().preConcat(SkM44(mxx, mxy, 0, mxt,
640-
myx, myy, 0, myt,
641-
0, 0, 1, 0,
642-
0, 0, 0, 1));
643-
current_layer_->update_matrix33();
637+
tracker_.transform2DAffine(mxx, mxy, mxt,
638+
myx, myy, myt);
644639
}
645640
}
646641
// full 4x4 transform in row major order
@@ -665,19 +660,17 @@ void DisplayListBuilder::transformFullPerspective(
665660
myx, myy, myz, myt,
666661
mzx, mzy, mzz, mzt,
667662
mwx, mwy, mwz, mwt);
668-
current_layer_->matrix().preConcat(SkM44(mxx, mxy, mxz, mxt,
669-
myx, myy, myz, myt,
670-
mzx, mzy, mzz, mzt,
671-
mwx, mwy, mwz, mwt));
672-
current_layer_->update_matrix33();
663+
tracker_.transformFullPerspective(mxx, mxy, mxz, mxt,
664+
myx, myy, myz, myt,
665+
mzx, mzy, mzz, mzt,
666+
mwx, mwy, mwz, mwt);
673667
}
674668
}
675669
// clang-format on
676670
void DisplayListBuilder::transformReset() {
677671
checkForDeferredSave();
678672
Push<TransformResetOp>(0, 0);
679-
current_layer_->matrix().setIdentity();
680-
current_layer_->update_matrix33();
673+
tracker_.setIdentity();
681674
}
682675
void DisplayListBuilder::transform(const SkMatrix* matrix) {
683676
if (matrix != nullptr) {
@@ -704,12 +697,12 @@ void DisplayListBuilder::clipRect(const SkRect& rect,
704697
switch (clip_op) {
705698
case SkClipOp::kIntersect:
706699
Push<ClipIntersectRectOp>(0, 1, rect, is_aa);
707-
intersect(rect);
708700
break;
709701
case SkClipOp::kDifference:
710702
Push<ClipDifferenceRectOp>(0, 1, rect, is_aa);
711703
break;
712704
}
705+
tracker_.clipRect(rect, clip_op, is_aa);
713706
}
714707
void DisplayListBuilder::clipRRect(const SkRRect& rrect,
715708
SkClipOp clip_op,
@@ -721,12 +714,12 @@ void DisplayListBuilder::clipRRect(const SkRRect& rrect,
721714
switch (clip_op) {
722715
case SkClipOp::kIntersect:
723716
Push<ClipIntersectRRectOp>(0, 1, rrect, is_aa);
724-
intersect(rrect.getBounds());
725717
break;
726718
case SkClipOp::kDifference:
727719
Push<ClipDifferenceRRectOp>(0, 1, rrect, is_aa);
728720
break;
729721
}
722+
tracker_.clipRRect(rrect, clip_op, is_aa);
730723
}
731724
}
732725
void DisplayListBuilder::clipPath(const SkPath& path,
@@ -753,48 +746,16 @@ void DisplayListBuilder::clipPath(const SkPath& path,
753746
switch (clip_op) {
754747
case SkClipOp::kIntersect:
755748
Push<ClipIntersectPathOp>(0, 1, path, is_aa);
756-
if (!path.isInverseFillType()) {
757-
intersect(path.getBounds());
758-
}
759749
break;
760750
case SkClipOp::kDifference:
761751
Push<ClipDifferencePathOp>(0, 1, path, is_aa);
762-
// Map "kDifference of inverse path" to "kIntersect of the original path".
763-
if (path.isInverseFillType()) {
764-
intersect(path.getBounds());
765-
}
766752
break;
767753
}
768-
}
769-
void DisplayListBuilder::intersect(const SkRect& rect) {
770-
SkRect dev_clip_bounds = getTransform().mapRect(rect);
771-
if (!current_layer_->clip_bounds().intersect(dev_clip_bounds)) {
772-
current_layer_->clip_bounds().setEmpty();
773-
}
774-
}
775-
SkRect DisplayListBuilder::getLocalClipBounds() {
776-
SkM44 inverse;
777-
if (current_layer_->matrix().invert(&inverse)) {
778-
SkRect dev_bounds;
779-
current_layer_->clip_bounds().roundOut(&dev_bounds);
780-
return inverse.asM33().mapRect(dev_bounds);
781-
}
782-
return kMaxCullRect;
754+
tracker_.clipPath(path, clip_op, is_aa);
783755
}
784756

785757
bool DisplayListBuilder::quickReject(const SkRect& bounds) const {
786-
if (bounds.isEmpty()) {
787-
return true;
788-
}
789-
SkMatrix matrix = getTransform();
790-
// We don't need the inverse, but this method tells us if the matrix
791-
// is singular in which case we can reject all rendering.
792-
if (!matrix.invert(nullptr)) {
793-
return true;
794-
}
795-
SkRect dev_bounds;
796-
matrix.mapRect(bounds).roundOut(&dev_bounds);
797-
return !current_layer_->clip_bounds().intersects(dev_bounds);
758+
return tracker_.content_culled(bounds);
798759
}
799760

800761
void DisplayListBuilder::drawPaint() {
@@ -1357,7 +1318,7 @@ bool DisplayListBuilder::AdjustBoundsForPaint(SkRect& bounds,
13571318
}
13581319

13591320
void DisplayListBuilder::AccumulateUnbounded() {
1360-
accumulator()->accumulate(current_layer_->clip_bounds());
1321+
accumulator()->accumulate(tracker_.device_cull_rect());
13611322
}
13621323

13631324
void DisplayListBuilder::AccumulateOpBounds(SkRect& bounds,
@@ -1369,8 +1330,8 @@ void DisplayListBuilder::AccumulateOpBounds(SkRect& bounds,
13691330
}
13701331
}
13711332
void DisplayListBuilder::AccumulateBounds(SkRect& bounds) {
1372-
getTransform().mapRect(&bounds);
1373-
if (bounds.intersect(current_layer_->clip_bounds())) {
1333+
tracker_.mapRect(&bounds);
1334+
if (bounds.intersect(tracker_.device_cull_rect())) {
13741335
accumulator()->accumulate(bounds);
13751336
}
13761337
}

display_list/display_list_builder.h

Lines changed: 7 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "flutter/display_list/display_list_dispatcher.h"
1212
#include "flutter/display_list/display_list_flags.h"
1313
#include "flutter/display_list/display_list_image.h"
14+
#include "flutter/display_list/display_list_matrix_clip_tracker.h"
1415
#include "flutter/display_list/display_list_paint.h"
1516
#include "flutter/display_list/display_list_path_effect.h"
1617
#include "flutter/display_list/display_list_sampling_options.h"
@@ -210,11 +211,11 @@ class DisplayListBuilder final : public virtual Dispatcher,
210211
/// Returns the 4x4 full perspective transform representing all transform
211212
/// operations executed so far in this DisplayList within the enclosing
212213
/// save stack.
213-
SkM44 getTransformFullPerspective() const { return current_layer_->matrix(); }
214+
SkM44 getTransformFullPerspective() const { return tracker_.matrix_4x4(); }
214215
/// Returns the 3x3 partial perspective transform representing all transform
215216
/// operations executed so far in this DisplayList within the enclosing
216217
/// save stack.
217-
SkMatrix getTransform() const { return current_layer_->matrix33(); }
218+
SkMatrix getTransform() const { return tracker_.matrix_3x3(); }
218219

219220
void clipRect(const SkRect& rect, SkClipOp clip_op, bool is_aa) override;
220221
void clipRRect(const SkRRect& rrect, SkClipOp clip_op, bool is_aa) override;
@@ -223,11 +224,11 @@ class DisplayListBuilder final : public virtual Dispatcher,
223224
/// Conservative estimate of the bounds of all outstanding clip operations
224225
/// measured in the coordinate space within which this DisplayList will
225226
/// be rendered.
226-
SkRect getDestinationClipBounds() { return current_layer_->clip_bounds(); }
227+
SkRect getDestinationClipBounds() { return tracker_.device_cull_rect(); }
227228
/// Conservative estimate of the bounds of all outstanding clip operations
228229
/// transformed into the local coordinate space in which currently
229230
/// recorded rendering operations are interpreted.
230-
SkRect getLocalClipBounds();
231+
SkRect getLocalClipBounds() { return tracker_.local_cull_rect(); }
231232

232233
/// Return true iff the supplied bounds are easily shown to be outside
233234
/// of the current clip bounds. This method may conservatively return
@@ -386,33 +387,16 @@ class DisplayListBuilder final : public virtual Dispatcher,
386387

387388
class LayerInfo {
388389
public:
389-
explicit LayerInfo(const SkM44& matrix,
390-
const SkMatrix& matrix33,
391-
const SkRect& clip_bounds,
392-
size_t save_layer_offset = 0,
390+
explicit LayerInfo(size_t save_layer_offset = 0,
393391
bool has_layer = false,
394392
std::shared_ptr<const DlImageFilter> filter = nullptr)
395393
: save_layer_offset_(save_layer_offset),
396394
has_layer_(has_layer),
397395
cannot_inherit_opacity_(false),
398396
has_compatible_op_(false),
399-
matrix_(matrix),
400-
matrix33_(matrix33),
401-
clip_bounds_(clip_bounds),
402397
filter_(filter),
403398
is_unbounded_(false) {}
404399

405-
explicit LayerInfo(const LayerInfo* current_layer,
406-
size_t save_layer_offset = 0,
407-
bool has_layer = false,
408-
std::shared_ptr<const DlImageFilter> filter = nullptr)
409-
: LayerInfo(current_layer->matrix_,
410-
current_layer->matrix33_,
411-
current_layer->clip_bounds_,
412-
save_layer_offset,
413-
has_layer,
414-
filter) {}
415-
416400
// The offset into the memory buffer where the saveLayer DLOp record
417401
// for this saveLayer() call is placed. This may be needed if the
418402
// eventual restore() call has discovered important information about
@@ -424,11 +408,6 @@ class DisplayListBuilder final : public virtual Dispatcher,
424408
bool has_layer() const { return has_layer_; }
425409
bool cannot_inherit_opacity() const { return cannot_inherit_opacity_; }
426410
bool has_compatible_op() const { return cannot_inherit_opacity_; }
427-
SkM44& matrix() { return matrix_; }
428-
SkMatrix& matrix33() { return matrix33_; }
429-
SkRect& clip_bounds() { return clip_bounds_; }
430-
431-
void update_matrix33() { matrix33_ = matrix_.asM33(); }
432411

433412
bool is_group_opacity_compatible() const {
434413
return !cannot_inherit_opacity_;
@@ -486,9 +465,6 @@ class DisplayListBuilder final : public virtual Dispatcher,
486465
bool has_layer_;
487466
bool cannot_inherit_opacity_;
488467
bool has_compatible_op_;
489-
SkM44 matrix_;
490-
SkMatrix matrix33_;
491-
SkRect clip_bounds_;
492468
std::shared_ptr<const DlImageFilter> filter_;
493469
bool is_unbounded_;
494470
bool has_deferred_save_op_ = false;
@@ -498,6 +474,7 @@ class DisplayListBuilder final : public virtual Dispatcher,
498474

499475
std::vector<LayerInfo> layer_stack_;
500476
LayerInfo* current_layer_;
477+
DisplayListMatrixClipTracker tracker_;
501478
std::unique_ptr<BoundsAccumulator> accumulator_;
502479
BoundsAccumulator* accumulator() { return accumulator_.get(); }
503480

0 commit comments

Comments
 (0)