Use DisplayListMatrixClipTracker in DisplayListBuilder (#38349)

* Use DisplayListMatrixClipTracker in DisplayListBuilder

* Ignore is_aa

* Revert "Ignore is_aa"

This reverts commit b201dadc773f8e726ec68ed88114df9be7b5a9b0.

* Tweak code

* Use content_culled

* getLocalClipBounds without device clip bounds roundsOut

* Tweak code and add more tests

* remove virtual
diff --git a/display_list/display_list_builder.cc b/display_list/display_list_builder.cc
index 14289a3..6cb5d6c 100644
--- a/display_list/display_list_builder.cc
+++ b/display_list/display_list_builder.cc
@@ -67,16 +67,15 @@
 }
 
 DisplayListBuilder::DisplayListBuilder(const SkRect& cull_rect,
-                                       bool prepare_rtree) {
+                                       bool prepare_rtree)
+    : tracker_(cull_rect, SkMatrix::I()) {
   if (prepare_rtree) {
     accumulator_ = std::make_unique<RTreeBoundsAccumulator>();
   } else {
     accumulator_ = std::make_unique<RectBoundsAccumulator>();
   }
 
-  // isEmpty protects us against NaN as we normalize any empty cull rects
-  SkRect cull = cull_rect.isEmpty() ? SkRect::MakeEmpty() : cull_rect;
-  layer_stack_.emplace_back(SkM44(), SkMatrix::I(), cull);
+  layer_stack_.emplace_back();
   current_layer_ = &layer_stack_.back();
 }
 
@@ -440,9 +439,10 @@
 }
 
 void DisplayListBuilder::save() {
-  layer_stack_.emplace_back(current_layer_);
+  layer_stack_.emplace_back();
   current_layer_ = &layer_stack_.back();
   current_layer_->has_deferred_save_op_ = true;
+  tracker_.save();
   accumulator()->save();
 }
 
@@ -455,6 +455,7 @@
     // on the stack.
     LayerInfo layer_info = layer_stack_.back();
 
+    tracker_.restore();
     layer_stack_.pop_back();
     current_layer_ = &layer_stack_.back();
     bool is_unbounded = layer_info.is_unbounded();
@@ -463,7 +464,7 @@
     // current accumulator and adjust it as required based on the filter.
     std::shared_ptr<const DlImageFilter> filter = layer_info.filter();
     if (filter) {
-      const SkRect* clip = &current_layer_->clip_bounds();
+      const SkRect clip = tracker_.device_cull_rect();
       if (!accumulator()->restore(
               [filter = filter, matrix = getTransform()](const SkRect& input,
                                                          SkRect& output) {
@@ -473,7 +474,7 @@
                 output.set(output_bounds);
                 return ret;
               },
-              clip)) {
+              &clip)) {
         is_unbounded = true;
       }
     } else {
@@ -544,11 +545,12 @@
       // We will fill the clip of the outer layer when we restore
       AccumulateUnbounded();
     }
-    layer_stack_.emplace_back(current_layer_, save_layer_offset, true,
+    layer_stack_.emplace_back(save_layer_offset, true,
                               current_.getImageFilter());
   } else {
-    layer_stack_.emplace_back(current_layer_, save_layer_offset, true, nullptr);
+    layer_stack_.emplace_back(save_layer_offset, true, nullptr);
   }
+  tracker_.save();
   accumulator()->save();
   current_layer_ = &layer_stack_.back();
   if (options.renders_with_attributes()) {
@@ -566,7 +568,7 @@
   // use them as the temporary layer bounds during rendering the layer, so
   // we set them as if a clip operation were performed.
   if (bounds) {
-    intersect(*bounds);
+    tracker_.clipRect(*bounds, SkClipOp::kIntersect, false);
   }
   if (backdrop) {
     // A backdrop will affect up to the entire surface, bounded by the clip
@@ -590,8 +592,7 @@
       (tx != 0.0 || ty != 0.0)) {
     checkForDeferredSave();
     Push<TranslateOp>(0, 1, tx, ty);
-    current_layer_->matrix().preTranslate(tx, ty);
-    current_layer_->update_matrix33();
+    tracker_.translate(tx, ty);
   }
 }
 void DisplayListBuilder::scale(SkScalar sx, SkScalar sy) {
@@ -599,16 +600,14 @@
       (sx != 1.0 || sy != 1.0)) {
     checkForDeferredSave();
     Push<ScaleOp>(0, 1, sx, sy);
-    current_layer_->matrix().preScale(sx, sy);
-    current_layer_->update_matrix33();
+    tracker_.scale(sx, sy);
   }
 }
 void DisplayListBuilder::rotate(SkScalar degrees) {
   if (SkScalarMod(degrees, 360.0) != 0.0) {
     checkForDeferredSave();
     Push<RotateOp>(0, 1, degrees);
-    current_layer_->matrix().preConcat(SkMatrix::RotateDeg(degrees));
-    current_layer_->update_matrix33();
+    tracker_.rotate(degrees);
   }
 }
 void DisplayListBuilder::skew(SkScalar sx, SkScalar sy) {
@@ -616,8 +615,7 @@
       (sx != 0.0 || sy != 0.0)) {
     checkForDeferredSave();
     Push<SkewOp>(0, 1, sx, sy);
-    current_layer_->matrix().preConcat(SkMatrix::Skew(sx, sy));
-    current_layer_->update_matrix33();
+    tracker_.skew(sx, sy);
   }
 }
 
@@ -636,11 +634,8 @@
     Push<Transform2DAffineOp>(0, 1,
                               mxx, mxy, mxt,
                               myx, myy, myt);
-    current_layer_->matrix().preConcat(SkM44(mxx, mxy,  0,  mxt,
-                                             myx, myy,  0,  myt,
-                                             0,   0,   1,   0,
-                                             0,   0,   0,   1));
-    current_layer_->update_matrix33();
+    tracker_.transform2DAffine(mxx, mxy, mxt,
+                               myx, myy, myt);
   }
 }
 // full 4x4 transform in row major order
@@ -665,19 +660,17 @@
                                      myx, myy, myz, myt,
                                      mzx, mzy, mzz, mzt,
                                      mwx, mwy, mwz, mwt);
-    current_layer_->matrix().preConcat(SkM44(mxx, mxy, mxz, mxt,
-                                             myx, myy, myz, myt,
-                                             mzx, mzy, mzz, mzt,
-                                             mwx, mwy, mwz, mwt));
-    current_layer_->update_matrix33();
+    tracker_.transformFullPerspective(mxx, mxy, mxz, mxt,
+                                      myx, myy, myz, myt,
+                                      mzx, mzy, mzz, mzt,
+                                      mwx, mwy, mwz, mwt);
   }
 }
 // clang-format on
 void DisplayListBuilder::transformReset() {
   checkForDeferredSave();
   Push<TransformResetOp>(0, 0);
-  current_layer_->matrix().setIdentity();
-  current_layer_->update_matrix33();
+  tracker_.setIdentity();
 }
 void DisplayListBuilder::transform(const SkMatrix* matrix) {
   if (matrix != nullptr) {
@@ -704,12 +697,12 @@
   switch (clip_op) {
     case SkClipOp::kIntersect:
       Push<ClipIntersectRectOp>(0, 1, rect, is_aa);
-      intersect(rect);
       break;
     case SkClipOp::kDifference:
       Push<ClipDifferenceRectOp>(0, 1, rect, is_aa);
       break;
   }
+  tracker_.clipRect(rect, clip_op, is_aa);
 }
 void DisplayListBuilder::clipRRect(const SkRRect& rrect,
                                    SkClipOp clip_op,
@@ -721,12 +714,12 @@
     switch (clip_op) {
       case SkClipOp::kIntersect:
         Push<ClipIntersectRRectOp>(0, 1, rrect, is_aa);
-        intersect(rrect.getBounds());
         break;
       case SkClipOp::kDifference:
         Push<ClipDifferenceRRectOp>(0, 1, rrect, is_aa);
         break;
     }
+    tracker_.clipRRect(rrect, clip_op, is_aa);
   }
 }
 void DisplayListBuilder::clipPath(const SkPath& path,
@@ -753,48 +746,16 @@
   switch (clip_op) {
     case SkClipOp::kIntersect:
       Push<ClipIntersectPathOp>(0, 1, path, is_aa);
-      if (!path.isInverseFillType()) {
-        intersect(path.getBounds());
-      }
       break;
     case SkClipOp::kDifference:
       Push<ClipDifferencePathOp>(0, 1, path, is_aa);
-      // Map "kDifference of inverse path" to "kIntersect of the original path".
-      if (path.isInverseFillType()) {
-        intersect(path.getBounds());
-      }
       break;
   }
-}
-void DisplayListBuilder::intersect(const SkRect& rect) {
-  SkRect dev_clip_bounds = getTransform().mapRect(rect);
-  if (!current_layer_->clip_bounds().intersect(dev_clip_bounds)) {
-    current_layer_->clip_bounds().setEmpty();
-  }
-}
-SkRect DisplayListBuilder::getLocalClipBounds() {
-  SkM44 inverse;
-  if (current_layer_->matrix().invert(&inverse)) {
-    SkRect dev_bounds;
-    current_layer_->clip_bounds().roundOut(&dev_bounds);
-    return inverse.asM33().mapRect(dev_bounds);
-  }
-  return kMaxCullRect;
+  tracker_.clipPath(path, clip_op, is_aa);
 }
 
 bool DisplayListBuilder::quickReject(const SkRect& bounds) const {
-  if (bounds.isEmpty()) {
-    return true;
-  }
-  SkMatrix matrix = getTransform();
-  // We don't need the inverse, but this method tells us if the matrix
-  // is singular in which case we can reject all rendering.
-  if (!matrix.invert(nullptr)) {
-    return true;
-  }
-  SkRect dev_bounds;
-  matrix.mapRect(bounds).roundOut(&dev_bounds);
-  return !current_layer_->clip_bounds().intersects(dev_bounds);
+  return tracker_.content_culled(bounds);
 }
 
 void DisplayListBuilder::drawPaint() {
@@ -1357,7 +1318,7 @@
 }
 
 void DisplayListBuilder::AccumulateUnbounded() {
-  accumulator()->accumulate(current_layer_->clip_bounds());
+  accumulator()->accumulate(tracker_.device_cull_rect());
 }
 
 void DisplayListBuilder::AccumulateOpBounds(SkRect& bounds,
@@ -1369,8 +1330,8 @@
   }
 }
 void DisplayListBuilder::AccumulateBounds(SkRect& bounds) {
-  getTransform().mapRect(&bounds);
-  if (bounds.intersect(current_layer_->clip_bounds())) {
+  tracker_.mapRect(&bounds);
+  if (bounds.intersect(tracker_.device_cull_rect())) {
     accumulator()->accumulate(bounds);
   }
 }