@@ -67,16 +67,15 @@ sk_sp<DisplayList> DisplayListBuilder::Build() {
6767}
6868
6969DisplayListBuilder::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
442441void 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 = ¤t_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}
597598void 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}
606606void 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}
614613void 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
676670void DisplayListBuilder::transformReset () {
677671 checkForDeferredSave ();
678672 Push<TransformResetOp>(0 , 0 );
679- current_layer_->matrix ().setIdentity ();
680- current_layer_->update_matrix33 ();
673+ tracker_.setIdentity ();
681674}
682675void 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}
714707void 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}
732725void 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
785757bool 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
800761void DisplayListBuilder::drawPaint () {
@@ -1357,7 +1318,7 @@ bool DisplayListBuilder::AdjustBoundsForPaint(SkRect& bounds,
13571318}
13581319
13591320void DisplayListBuilder::AccumulateUnbounded () {
1360- accumulator ()->accumulate (current_layer_-> clip_bounds ());
1321+ accumulator ()->accumulate (tracker_. device_cull_rect ());
13611322}
13621323
13631324void DisplayListBuilder::AccumulateOpBounds (SkRect& bounds,
@@ -1369,8 +1330,8 @@ void DisplayListBuilder::AccumulateOpBounds(SkRect& bounds,
13691330 }
13701331}
13711332void 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}
0 commit comments