@@ -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