@@ -65,7 +65,7 @@ sk_sp<DisplayList> DisplayListBuilder::Build() {
6565
6666DisplayListBuilder::DisplayListBuilder (const SkRect& cull_rect)
6767 : cull_rect_(cull_rect) {
68- layer_stack_.emplace_back ();
68+ layer_stack_.emplace_back (SkM44 (), cull_rect );
6969 current_layer_ = &layer_stack_.back ();
7070}
7171
@@ -415,7 +415,7 @@ void DisplayListBuilder::setAttributesFromPaint(
415415
416416void DisplayListBuilder::save () {
417417 Push<SaveOp>(0 , 1 );
418- layer_stack_.emplace_back ();
418+ layer_stack_.emplace_back (current_layer_ );
419419 current_layer_ = &layer_stack_.back ();
420420}
421421void DisplayListBuilder::restore () {
@@ -476,7 +476,7 @@ void DisplayListBuilder::saveLayer(const SkRect* bounds,
476476 : Push<SaveLayerOp>(0 , 1 , options);
477477 }
478478 CheckLayerOpacityCompatibility (options.renders_with_attributes ());
479- layer_stack_.emplace_back (save_layer_offset, true );
479+ layer_stack_.emplace_back (current_layer_, save_layer_offset, true );
480480 current_layer_ = &layer_stack_.back ();
481481 if (options.renders_with_attributes ()) {
482482 // |current_opacity_compatibility_| does not take an ImageFilter into
@@ -505,23 +505,27 @@ void DisplayListBuilder::translate(SkScalar tx, SkScalar ty) {
505505 if (SkScalarIsFinite (tx) && SkScalarIsFinite (ty) &&
506506 (tx != 0.0 || ty != 0.0 )) {
507507 Push<TranslateOp>(0 , 1 , tx, ty);
508+ current_layer_->matrix .preTranslate (tx, ty);
508509 }
509510}
510511void DisplayListBuilder::scale (SkScalar sx, SkScalar sy) {
511512 if (SkScalarIsFinite (sx) && SkScalarIsFinite (sy) &&
512513 (sx != 1.0 || sy != 1.0 )) {
513514 Push<ScaleOp>(0 , 1 , sx, sy);
515+ current_layer_->matrix .preScale (sx, sy);
514516 }
515517}
516518void DisplayListBuilder::rotate (SkScalar degrees) {
517519 if (SkScalarMod (degrees, 360.0 ) != 0.0 ) {
518520 Push<RotateOp>(0 , 1 , degrees);
521+ current_layer_->matrix .preConcat (SkMatrix::RotateDeg (degrees));
519522 }
520523}
521524void DisplayListBuilder::skew (SkScalar sx, SkScalar sy) {
522525 if (SkScalarIsFinite (sx) && SkScalarIsFinite (sy) &&
523526 (sx != 0.0 || sy != 0.0 )) {
524527 Push<SkewOp>(0 , 1 , sx, sy);
528+ current_layer_->matrix .preConcat (SkMatrix::Skew (sx, sy));
525529 }
526530}
527531
@@ -539,6 +543,10 @@ void DisplayListBuilder::transform2DAffine(
539543 Push<Transform2DAffineOp>(0 , 1 ,
540544 mxx, mxy, mxt,
541545 myx, myy, myt);
546+ current_layer_->matrix .preConcat (SkM44 (mxx, mxy, 0 , mxt,
547+ myx, myy, 0 , myt,
548+ 0 , 0 , 1 , 0 ,
549+ 0 , 0 , 0 , 1 ));
542550 }
543551}
544552// full 4x4 transform in row major order
@@ -562,11 +570,16 @@ void DisplayListBuilder::transformFullPerspective(
562570 myx, myy, myz, myt,
563571 mzx, mzy, mzz, mzt,
564572 mwx, mwy, mwz, mwt);
573+ current_layer_->matrix .preConcat (SkM44 (mxx, mxy, mxz, mxt,
574+ myx, myy, myz, myt,
575+ mzx, mzy, mzz, mzt,
576+ mwx, mwy, mwz, mwt));
565577 }
566578}
567579// clang-format on
568580void DisplayListBuilder::transformReset () {
569581 Push<TransformResetOp>(0 , 0 );
582+ current_layer_->matrix .setIdentity ();
570583}
571584void DisplayListBuilder::transform (const SkMatrix* matrix) {
572585 if (matrix != nullptr ) {
@@ -586,19 +599,35 @@ void DisplayListBuilder::transform(const SkM44* m44) {
586599void DisplayListBuilder::clipRect (const SkRect& rect,
587600 SkClipOp clip_op,
588601 bool is_aa) {
589- clip_op == SkClipOp::kIntersect //
590- ? Push<ClipIntersectRectOp>(0 , 1 , rect, is_aa)
591- : Push<ClipDifferenceRectOp>(0 , 1 , rect, is_aa);
602+ switch (clip_op) {
603+ case SkClipOp::kIntersect :
604+ Push<ClipIntersectRectOp>(0 , 1 , rect, is_aa);
605+ if (!current_layer_->clip_bounds .intersect (rect)) {
606+ current_layer_->clip_bounds .setEmpty ();
607+ }
608+ break ;
609+ case SkClipOp::kDifference :
610+ Push<ClipDifferenceRectOp>(0 , 1 , rect, is_aa);
611+ break ;
612+ }
592613}
593614void DisplayListBuilder::clipRRect (const SkRRect& rrect,
594615 SkClipOp clip_op,
595616 bool is_aa) {
596617 if (rrect.isRect ()) {
597618 clipRect (rrect.rect (), clip_op, is_aa);
598619 } else {
599- clip_op == SkClipOp::kIntersect //
600- ? Push<ClipIntersectRRectOp>(0 , 1 , rrect, is_aa)
601- : Push<ClipDifferenceRRectOp>(0 , 1 , rrect, is_aa);
620+ switch (clip_op) {
621+ case SkClipOp::kIntersect :
622+ Push<ClipIntersectRRectOp>(0 , 1 , rrect, is_aa);
623+ if (!current_layer_->clip_bounds .intersect (rrect.getBounds ())) {
624+ current_layer_->clip_bounds .setEmpty ();
625+ }
626+ break ;
627+ case SkClipOp::kDifference :
628+ Push<ClipDifferenceRRectOp>(0 , 1 , rrect, is_aa);
629+ break ;
630+ }
602631 }
603632}
604633void DisplayListBuilder::clipPath (const SkPath& path,
@@ -621,9 +650,26 @@ void DisplayListBuilder::clipPath(const SkPath& path,
621650 return ;
622651 }
623652 }
624- clip_op == SkClipOp::kIntersect //
625- ? Push<ClipIntersectPathOp>(0 , 1 , path, is_aa)
626- : Push<ClipDifferencePathOp>(0 , 1 , path, is_aa);
653+ switch (clip_op) {
654+ case SkClipOp::kIntersect :
655+ Push<ClipIntersectPathOp>(0 , 1 , path, is_aa);
656+ if (!current_layer_->clip_bounds .intersect (path.getBounds ())) {
657+ current_layer_->clip_bounds .setEmpty ();
658+ }
659+ break ;
660+ case SkClipOp::kDifference :
661+ Push<ClipDifferencePathOp>(0 , 1 , path, is_aa);
662+ break ;
663+ }
664+ }
665+ SkRect DisplayListBuilder::getLocalClipBounds () {
666+ SkM44 inverse;
667+ if (current_layer_->matrix .invert (&inverse)) {
668+ SkRect devBounds;
669+ current_layer_->clip_bounds .roundOut (&devBounds);
670+ return inverse.asM33 ().mapRect (devBounds);
671+ }
672+ return kMaxCullRect_ ;
627673}
628674
629675void DisplayListBuilder::drawPaint () {
0 commit comments