@@ -67,16 +67,15 @@ sk_sp<DisplayList> DisplayListBuilder::Build() {
67
67
}
68
68
69
69
DisplayListBuilder::DisplayListBuilder (const SkRect& cull_rect,
70
- bool prepare_rtree) {
70
+ bool prepare_rtree)
71
+ : tracker_(cull_rect, SkMatrix::I()) {
71
72
if (prepare_rtree) {
72
73
accumulator_ = std::make_unique<RTreeBoundsAccumulator>();
73
74
} else {
74
75
accumulator_ = std::make_unique<RectBoundsAccumulator>();
75
76
}
76
77
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 ();
80
79
current_layer_ = &layer_stack_.back ();
81
80
}
82
81
@@ -440,9 +439,10 @@ void DisplayListBuilder::checkForDeferredSave() {
440
439
}
441
440
442
441
void DisplayListBuilder::save () {
443
- layer_stack_.emplace_back (current_layer_ );
442
+ layer_stack_.emplace_back ();
444
443
current_layer_ = &layer_stack_.back ();
445
444
current_layer_->has_deferred_save_op_ = true ;
445
+ tracker_.save ();
446
446
accumulator ()->save ();
447
447
}
448
448
@@ -455,6 +455,7 @@ void DisplayListBuilder::restore() {
455
455
// on the stack.
456
456
LayerInfo layer_info = layer_stack_.back ();
457
457
458
+ tracker_.restore ();
458
459
layer_stack_.pop_back ();
459
460
current_layer_ = &layer_stack_.back ();
460
461
bool is_unbounded = layer_info.is_unbounded ();
@@ -463,7 +464,7 @@ void DisplayListBuilder::restore() {
463
464
// current accumulator and adjust it as required based on the filter.
464
465
std::shared_ptr<const DlImageFilter> filter = layer_info.filter ();
465
466
if (filter) {
466
- const SkRect* clip = ¤t_layer_-> clip_bounds ();
467
+ const SkRect clip = tracker_. device_cull_rect ();
467
468
if (!accumulator ()->restore (
468
469
[filter = filter, matrix = getTransform ()](const SkRect& input,
469
470
SkRect& output) {
@@ -473,7 +474,7 @@ void DisplayListBuilder::restore() {
473
474
output.set (output_bounds);
474
475
return ret;
475
476
},
476
- clip)) {
477
+ & clip)) {
477
478
is_unbounded = true ;
478
479
}
479
480
} else {
@@ -544,11 +545,12 @@ void DisplayListBuilder::saveLayer(const SkRect* bounds,
544
545
// We will fill the clip of the outer layer when we restore
545
546
AccumulateUnbounded ();
546
547
}
547
- layer_stack_.emplace_back (current_layer_, save_layer_offset, true ,
548
+ layer_stack_.emplace_back (save_layer_offset, true ,
548
549
current_.getImageFilter ());
549
550
} else {
550
- layer_stack_.emplace_back (current_layer_, save_layer_offset, true , nullptr );
551
+ layer_stack_.emplace_back (save_layer_offset, true , nullptr );
551
552
}
553
+ tracker_.save ();
552
554
accumulator ()->save ();
553
555
current_layer_ = &layer_stack_.back ();
554
556
if (options.renders_with_attributes ()) {
@@ -566,7 +568,7 @@ void DisplayListBuilder::saveLayer(const SkRect* bounds,
566
568
// use them as the temporary layer bounds during rendering the layer, so
567
569
// we set them as if a clip operation were performed.
568
570
if (bounds) {
569
- intersect (*bounds);
571
+ tracker_. clipRect (*bounds, SkClipOp:: kIntersect , false );
570
572
}
571
573
if (backdrop) {
572
574
// A backdrop will affect up to the entire surface, bounded by the clip
@@ -590,34 +592,30 @@ void DisplayListBuilder::translate(SkScalar tx, SkScalar ty) {
590
592
(tx != 0.0 || ty != 0.0 )) {
591
593
checkForDeferredSave ();
592
594
Push<TranslateOp>(0 , 1 , tx, ty);
593
- current_layer_->matrix ().preTranslate (tx, ty);
594
- current_layer_->update_matrix33 ();
595
+ tracker_.translate (tx, ty);
595
596
}
596
597
}
597
598
void DisplayListBuilder::scale (SkScalar sx, SkScalar sy) {
598
599
if (SkScalarIsFinite (sx) && SkScalarIsFinite (sy) &&
599
600
(sx != 1.0 || sy != 1.0 )) {
600
601
checkForDeferredSave ();
601
602
Push<ScaleOp>(0 , 1 , sx, sy);
602
- current_layer_->matrix ().preScale (sx, sy);
603
- current_layer_->update_matrix33 ();
603
+ tracker_.scale (sx, sy);
604
604
}
605
605
}
606
606
void DisplayListBuilder::rotate (SkScalar degrees) {
607
607
if (SkScalarMod (degrees, 360.0 ) != 0.0 ) {
608
608
checkForDeferredSave ();
609
609
Push<RotateOp>(0 , 1 , degrees);
610
- current_layer_->matrix ().preConcat (SkMatrix::RotateDeg (degrees));
611
- current_layer_->update_matrix33 ();
610
+ tracker_.rotate (degrees);
612
611
}
613
612
}
614
613
void DisplayListBuilder::skew (SkScalar sx, SkScalar sy) {
615
614
if (SkScalarIsFinite (sx) && SkScalarIsFinite (sy) &&
616
615
(sx != 0.0 || sy != 0.0 )) {
617
616
checkForDeferredSave ();
618
617
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);
621
619
}
622
620
}
623
621
@@ -636,11 +634,8 @@ void DisplayListBuilder::transform2DAffine(
636
634
Push<Transform2DAffineOp>(0 , 1 ,
637
635
mxx, mxy, mxt,
638
636
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);
644
639
}
645
640
}
646
641
// full 4x4 transform in row major order
@@ -665,19 +660,17 @@ void DisplayListBuilder::transformFullPerspective(
665
660
myx, myy, myz, myt,
666
661
mzx, mzy, mzz, mzt,
667
662
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);
673
667
}
674
668
}
675
669
// clang-format on
676
670
void DisplayListBuilder::transformReset () {
677
671
checkForDeferredSave ();
678
672
Push<TransformResetOp>(0 , 0 );
679
- current_layer_->matrix ().setIdentity ();
680
- current_layer_->update_matrix33 ();
673
+ tracker_.setIdentity ();
681
674
}
682
675
void DisplayListBuilder::transform (const SkMatrix* matrix) {
683
676
if (matrix != nullptr ) {
@@ -704,12 +697,12 @@ void DisplayListBuilder::clipRect(const SkRect& rect,
704
697
switch (clip_op) {
705
698
case SkClipOp::kIntersect :
706
699
Push<ClipIntersectRectOp>(0 , 1 , rect, is_aa);
707
- intersect (rect);
708
700
break ;
709
701
case SkClipOp::kDifference :
710
702
Push<ClipDifferenceRectOp>(0 , 1 , rect, is_aa);
711
703
break ;
712
704
}
705
+ tracker_.clipRect (rect, clip_op, is_aa);
713
706
}
714
707
void DisplayListBuilder::clipRRect (const SkRRect& rrect,
715
708
SkClipOp clip_op,
@@ -721,12 +714,12 @@ void DisplayListBuilder::clipRRect(const SkRRect& rrect,
721
714
switch (clip_op) {
722
715
case SkClipOp::kIntersect :
723
716
Push<ClipIntersectRRectOp>(0 , 1 , rrect, is_aa);
724
- intersect (rrect.getBounds ());
725
717
break ;
726
718
case SkClipOp::kDifference :
727
719
Push<ClipDifferenceRRectOp>(0 , 1 , rrect, is_aa);
728
720
break ;
729
721
}
722
+ tracker_.clipRRect (rrect, clip_op, is_aa);
730
723
}
731
724
}
732
725
void DisplayListBuilder::clipPath (const SkPath& path,
@@ -753,48 +746,16 @@ void DisplayListBuilder::clipPath(const SkPath& path,
753
746
switch (clip_op) {
754
747
case SkClipOp::kIntersect :
755
748
Push<ClipIntersectPathOp>(0 , 1 , path, is_aa);
756
- if (!path.isInverseFillType ()) {
757
- intersect (path.getBounds ());
758
- }
759
749
break ;
760
750
case SkClipOp::kDifference :
761
751
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
- }
766
752
break ;
767
753
}
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);
783
755
}
784
756
785
757
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);
798
759
}
799
760
800
761
void DisplayListBuilder::drawPaint () {
@@ -1357,7 +1318,7 @@ bool DisplayListBuilder::AdjustBoundsForPaint(SkRect& bounds,
1357
1318
}
1358
1319
1359
1320
void DisplayListBuilder::AccumulateUnbounded () {
1360
- accumulator ()->accumulate (current_layer_-> clip_bounds ());
1321
+ accumulator ()->accumulate (tracker_. device_cull_rect ());
1361
1322
}
1362
1323
1363
1324
void DisplayListBuilder::AccumulateOpBounds (SkRect& bounds,
@@ -1369,8 +1330,8 @@ void DisplayListBuilder::AccumulateOpBounds(SkRect& bounds,
1369
1330
}
1370
1331
}
1371
1332
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 ())) {
1374
1335
accumulator ()->accumulate (bounds);
1375
1336
}
1376
1337
}
0 commit comments