@@ -65,7 +65,7 @@ sk_sp<DisplayList> DisplayListBuilder::Build() {
65
65
66
66
DisplayListBuilder::DisplayListBuilder (const SkRect& cull_rect)
67
67
: cull_rect_(cull_rect) {
68
- layer_stack_.emplace_back ();
68
+ layer_stack_.emplace_back (SkM44 (), cull_rect );
69
69
current_layer_ = &layer_stack_.back ();
70
70
}
71
71
@@ -415,7 +415,7 @@ void DisplayListBuilder::setAttributesFromPaint(
415
415
416
416
void DisplayListBuilder::save () {
417
417
Push<SaveOp>(0 , 1 );
418
- layer_stack_.emplace_back ();
418
+ layer_stack_.emplace_back (current_layer_ );
419
419
current_layer_ = &layer_stack_.back ();
420
420
}
421
421
void DisplayListBuilder::restore () {
@@ -476,7 +476,7 @@ void DisplayListBuilder::saveLayer(const SkRect* bounds,
476
476
: Push<SaveLayerOp>(0 , 1 , options);
477
477
}
478
478
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 );
480
480
current_layer_ = &layer_stack_.back ();
481
481
if (options.renders_with_attributes ()) {
482
482
// |current_opacity_compatibility_| does not take an ImageFilter into
@@ -505,23 +505,27 @@ void DisplayListBuilder::translate(SkScalar tx, SkScalar ty) {
505
505
if (SkScalarIsFinite (tx) && SkScalarIsFinite (ty) &&
506
506
(tx != 0.0 || ty != 0.0 )) {
507
507
Push<TranslateOp>(0 , 1 , tx, ty);
508
+ current_layer_->matrix .preTranslate (tx, ty);
508
509
}
509
510
}
510
511
void DisplayListBuilder::scale (SkScalar sx, SkScalar sy) {
511
512
if (SkScalarIsFinite (sx) && SkScalarIsFinite (sy) &&
512
513
(sx != 1.0 || sy != 1.0 )) {
513
514
Push<ScaleOp>(0 , 1 , sx, sy);
515
+ current_layer_->matrix .preScale (sx, sy);
514
516
}
515
517
}
516
518
void DisplayListBuilder::rotate (SkScalar degrees) {
517
519
if (SkScalarMod (degrees, 360.0 ) != 0.0 ) {
518
520
Push<RotateOp>(0 , 1 , degrees);
521
+ current_layer_->matrix .preConcat (SkMatrix::RotateDeg (degrees));
519
522
}
520
523
}
521
524
void DisplayListBuilder::skew (SkScalar sx, SkScalar sy) {
522
525
if (SkScalarIsFinite (sx) && SkScalarIsFinite (sy) &&
523
526
(sx != 0.0 || sy != 0.0 )) {
524
527
Push<SkewOp>(0 , 1 , sx, sy);
528
+ current_layer_->matrix .preConcat (SkMatrix::Skew (sx, sy));
525
529
}
526
530
}
527
531
@@ -539,6 +543,10 @@ void DisplayListBuilder::transform2DAffine(
539
543
Push<Transform2DAffineOp>(0 , 1 ,
540
544
mxx, mxy, mxt,
541
545
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 ));
542
550
}
543
551
}
544
552
// full 4x4 transform in row major order
@@ -562,11 +570,16 @@ void DisplayListBuilder::transformFullPerspective(
562
570
myx, myy, myz, myt,
563
571
mzx, mzy, mzz, mzt,
564
572
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));
565
577
}
566
578
}
567
579
// clang-format on
568
580
void DisplayListBuilder::transformReset () {
569
581
Push<TransformResetOp>(0 , 0 );
582
+ current_layer_->matrix .setIdentity ();
570
583
}
571
584
void DisplayListBuilder::transform (const SkMatrix* matrix) {
572
585
if (matrix != nullptr ) {
@@ -586,19 +599,35 @@ void DisplayListBuilder::transform(const SkM44* m44) {
586
599
void DisplayListBuilder::clipRect (const SkRect& rect,
587
600
SkClipOp clip_op,
588
601
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
+ }
592
613
}
593
614
void DisplayListBuilder::clipRRect (const SkRRect& rrect,
594
615
SkClipOp clip_op,
595
616
bool is_aa) {
596
617
if (rrect.isRect ()) {
597
618
clipRect (rrect.rect (), clip_op, is_aa);
598
619
} 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
+ }
602
631
}
603
632
}
604
633
void DisplayListBuilder::clipPath (const SkPath& path,
@@ -621,9 +650,26 @@ void DisplayListBuilder::clipPath(const SkPath& path,
621
650
return ;
622
651
}
623
652
}
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_ ;
627
673
}
628
674
629
675
void DisplayListBuilder::drawPaint () {
0 commit comments