@@ -67,16 +67,16 @@ 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.isEmpty() ? SkRect::MakeEmpty() : cull_rect,
72+ SkMatrix::I ()) {
7173 if (prepare_rtree) {
7274 accumulator_ = std::make_unique<RTreeBoundsAccumulator>();
7375 } else {
7476 accumulator_ = std::make_unique<RectBoundsAccumulator>();
7577 }
7678
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);
79+ layer_stack_.emplace_back (LayerInfo ());
8080 current_layer_ = &layer_stack_.back ();
8181}
8282
@@ -443,6 +443,7 @@ void DisplayListBuilder::save() {
443443 layer_stack_.emplace_back (current_layer_);
444444 current_layer_ = &layer_stack_.back ();
445445 current_layer_->has_deferred_save_op_ = true ;
446+ tracker_.save ();
446447 accumulator ()->save ();
447448}
448449
@@ -455,6 +456,7 @@ void DisplayListBuilder::restore() {
455456 // on the stack.
456457 LayerInfo layer_info = layer_stack_.back ();
457458
459+ tracker_.restore ();
458460 layer_stack_.pop_back ();
459461 current_layer_ = &layer_stack_.back ();
460462 bool is_unbounded = layer_info.is_unbounded ();
@@ -463,7 +465,7 @@ void DisplayListBuilder::restore() {
463465 // current accumulator and adjust it as required based on the filter.
464466 std::shared_ptr<const DlImageFilter> filter = layer_info.filter ();
465467 if (filter) {
466- const SkRect* clip = ¤t_layer_-> clip_bounds ();
468+ const SkRect clip = tracker_. device_cull_rect ();
467469 if (!accumulator ()->restore (
468470 [filter = filter, matrix = getTransform ()](const SkRect& input,
469471 SkRect& output) {
@@ -473,7 +475,7 @@ void DisplayListBuilder::restore() {
473475 output.set (output_bounds);
474476 return ret;
475477 },
476- clip)) {
478+ & clip)) {
477479 is_unbounded = true ;
478480 }
479481 } else {
@@ -549,6 +551,7 @@ void DisplayListBuilder::saveLayer(const SkRect* bounds,
549551 } else {
550552 layer_stack_.emplace_back (current_layer_, save_layer_offset, true , nullptr );
551553 }
554+ tracker_.save ();
552555 accumulator ()->save ();
553556 current_layer_ = &layer_stack_.back ();
554557 if (options.renders_with_attributes ()) {
@@ -566,7 +569,7 @@ void DisplayListBuilder::saveLayer(const SkRect* bounds,
566569 // use them as the temporary layer bounds during rendering the layer, so
567570 // we set them as if a clip operation were performed.
568571 if (bounds) {
569- intersect (*bounds);
572+ tracker_. clipRect (*bounds, SkClipOp:: kIntersect , false );
570573 }
571574 if (backdrop) {
572575 // A backdrop will affect up to the entire surface, bounded by the clip
@@ -590,34 +593,30 @@ void DisplayListBuilder::translate(SkScalar tx, SkScalar ty) {
590593 (tx != 0.0 || ty != 0.0 )) {
591594 checkForDeferredSave ();
592595 Push<TranslateOp>(0 , 1 , tx, ty);
593- current_layer_->matrix ().preTranslate (tx, ty);
594- current_layer_->update_matrix33 ();
596+ tracker_.translate (tx, ty);
595597 }
596598}
597599void DisplayListBuilder::scale (SkScalar sx, SkScalar sy) {
598600 if (SkScalarIsFinite (sx) && SkScalarIsFinite (sy) &&
599601 (sx != 1.0 || sy != 1.0 )) {
600602 checkForDeferredSave ();
601603 Push<ScaleOp>(0 , 1 , sx, sy);
602- current_layer_->matrix ().preScale (sx, sy);
603- current_layer_->update_matrix33 ();
604+ tracker_.scale (sx, sy);
604605 }
605606}
606607void DisplayListBuilder::rotate (SkScalar degrees) {
607608 if (SkScalarMod (degrees, 360.0 ) != 0.0 ) {
608609 checkForDeferredSave ();
609610 Push<RotateOp>(0 , 1 , degrees);
610- current_layer_->matrix ().preConcat (SkMatrix::RotateDeg (degrees));
611- current_layer_->update_matrix33 ();
611+ tracker_.rotate (degrees);
612612 }
613613}
614614void DisplayListBuilder::skew (SkScalar sx, SkScalar sy) {
615615 if (SkScalarIsFinite (sx) && SkScalarIsFinite (sy) &&
616616 (sx != 0.0 || sy != 0.0 )) {
617617 checkForDeferredSave ();
618618 Push<SkewOp>(0 , 1 , sx, sy);
619- current_layer_->matrix ().preConcat (SkMatrix::Skew (sx, sy));
620- current_layer_->update_matrix33 ();
619+ tracker_.skew (sx, sy);
621620 }
622621}
623622
@@ -636,11 +635,10 @@ void DisplayListBuilder::transform2DAffine(
636635 Push<Transform2DAffineOp>(0 , 1 ,
637636 mxx, mxy, mxt,
638637 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 ();
638+ tracker_.transform (SkM44 (mxx, mxy, 0 , mxt,
639+ myx, myy, 0 , myt,
640+ 0 , 0 , 1 , 0 ,
641+ 0 , 0 , 0 , 1 ));
644642 }
645643}
646644// full 4x4 transform in row major order
@@ -665,19 +663,17 @@ void DisplayListBuilder::transformFullPerspective(
665663 myx, myy, myz, myt,
666664 mzx, mzy, mzz, mzt,
667665 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 ();
666+ tracker_.transform (SkM44 (mxx, mxy, mxz, mxt,
667+ myx, myy, myz, myt,
668+ mzx, mzy, mzz, mzt,
669+ mwx, mwy, mwz, mwt));
673670 }
674671}
675672// clang-format on
676673void DisplayListBuilder::transformReset () {
677674 checkForDeferredSave ();
678675 Push<TransformResetOp>(0 , 0 );
679- current_layer_->matrix ().setIdentity ();
680- current_layer_->update_matrix33 ();
676+ tracker_.setIdentity ();
681677}
682678void DisplayListBuilder::transform (const SkMatrix* matrix) {
683679 if (matrix != nullptr ) {
@@ -704,12 +700,12 @@ void DisplayListBuilder::clipRect(const SkRect& rect,
704700 switch (clip_op) {
705701 case SkClipOp::kIntersect :
706702 Push<ClipIntersectRectOp>(0 , 1 , rect, is_aa);
707- intersect (rect);
708703 break ;
709704 case SkClipOp::kDifference :
710705 Push<ClipDifferenceRectOp>(0 , 1 , rect, is_aa);
711706 break ;
712707 }
708+ tracker_.clipRect (rect, clip_op, is_aa);
713709}
714710void DisplayListBuilder::clipRRect (const SkRRect& rrect,
715711 SkClipOp clip_op,
@@ -721,12 +717,12 @@ void DisplayListBuilder::clipRRect(const SkRRect& rrect,
721717 switch (clip_op) {
722718 case SkClipOp::kIntersect :
723719 Push<ClipIntersectRRectOp>(0 , 1 , rrect, is_aa);
724- intersect (rrect.getBounds ());
725720 break ;
726721 case SkClipOp::kDifference :
727722 Push<ClipDifferenceRRectOp>(0 , 1 , rrect, is_aa);
728723 break ;
729724 }
725+ tracker_.clipRRect (rrect, clip_op, is_aa);
730726 }
731727}
732728void DisplayListBuilder::clipPath (const SkPath& path,
@@ -753,33 +749,12 @@ void DisplayListBuilder::clipPath(const SkPath& path,
753749 switch (clip_op) {
754750 case SkClipOp::kIntersect :
755751 Push<ClipIntersectPathOp>(0 , 1 , path, is_aa);
756- if (!path.isInverseFillType ()) {
757- intersect (path.getBounds ());
758- }
759752 break ;
760753 case SkClipOp::kDifference :
761754 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- }
766755 break ;
767756 }
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 ;
757+ tracker_.clipPath (path, clip_op, is_aa);
783758}
784759
785760bool DisplayListBuilder::quickReject (const SkRect& bounds) const {
@@ -794,7 +769,7 @@ bool DisplayListBuilder::quickReject(const SkRect& bounds) const {
794769 }
795770 SkRect dev_bounds;
796771 matrix.mapRect (bounds).roundOut (&dev_bounds);
797- return !current_layer_-> clip_bounds ().intersects (dev_bounds);
772+ return !tracker_. device_cull_rect ().intersects (dev_bounds);
798773}
799774
800775void DisplayListBuilder::drawPaint () {
@@ -1357,7 +1332,7 @@ bool DisplayListBuilder::AdjustBoundsForPaint(SkRect& bounds,
13571332}
13581333
13591334void DisplayListBuilder::AccumulateUnbounded () {
1360- accumulator ()->accumulate (current_layer_-> clip_bounds ());
1335+ accumulator ()->accumulate (tracker_. device_cull_rect ());
13611336}
13621337
13631338void DisplayListBuilder::AccumulateOpBounds (SkRect& bounds,
@@ -1370,7 +1345,7 @@ void DisplayListBuilder::AccumulateOpBounds(SkRect& bounds,
13701345}
13711346void DisplayListBuilder::AccumulateBounds (SkRect& bounds) {
13721347 getTransform ().mapRect (&bounds);
1373- if (bounds.intersect (current_layer_-> clip_bounds ())) {
1348+ if (bounds.intersect (tracker_. device_cull_rect ())) {
13741349 accumulator ()->accumulate (bounds);
13751350 }
13761351}
0 commit comments