Avoid SetNeedsCullRectUpdate() if using and will use infinite cull rect

Bug: 1253726
Change-Id: I4d938b3d2222542b6d578a076e18720263f3ee6e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3877498
Reviewed-by: Philip Rogers <pdr@chromium.org>
Commit-Queue: Xianzhu Wang <wangxianzhu@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1044695}
diff --git a/third_party/blink/renderer/core/paint/cull_rect_updater.cc b/third_party/blink/renderer/core/paint/cull_rect_updater.cc
index a088259..a457376 100644
--- a/third_party/blink/renderer/core/paint/cull_rect_updater.cc
+++ b/third_party/blink/renderer/core/paint/cull_rect_updater.cc
@@ -441,6 +441,8 @@
 void CullRectUpdater::PaintPropertiesChanged(
     const LayoutObject& object,
     const PaintPropertiesChangeInfo& properties_changed) {
+  DCHECK(RuntimeEnabledFeatures::ScrollUpdateOptimizationsEnabled());
+
   // We don't need to update cull rect for kChangedOnlyCompositedValues (except
   // for some paint translation changes, see below) because we expect no repaint
   // or PAC update for performance.
@@ -452,6 +454,19 @@
   DCHECK_NE(properties_changed.scroll_changed,
             PaintPropertyChangeType::kChangedOnlyCompositedValues);
 
+  bool should_use_infinite_cull_rect = false;
+  if (object.HasLayer()) {
+    bool subtree_should_use_infinite_cull_rect = false;
+    should_use_infinite_cull_rect =
+        ShouldUseInfiniteCullRect(*To<LayoutBoxModelObject>(object).Layer(),
+                                  subtree_should_use_infinite_cull_rect);
+    if (should_use_infinite_cull_rect &&
+        object.FirstFragment().GetCullRect().IsInfinite() &&
+        object.FirstFragment().GetContentsCullRect().IsInfinite()) {
+      return;
+    }
+  }
+
   // Cull rects depend on transforms, clip rects, scroll contents sizes and
   // scroll offsets.
   bool needs_cull_rect_update =
@@ -467,12 +482,9 @@
     // For cases that the transform change can be directly updated, we should
     // use infinite cull rect or rect expanded for composied scroll (in case of
     // not scrolled enough) to avoid cull rect change and repaint.
-    bool subtree_should_use_infinite_cull_rect = false;
     DCHECK(properties_changed.transform_changed !=
                PaintPropertyChangeType::kChangedOnlyCompositedValues ||
-           object.IsSVGChild() ||
-           ShouldUseInfiniteCullRect(*To<LayoutBoxModelObject>(object).Layer(),
-                                     subtree_should_use_infinite_cull_rect) ||
+           object.IsSVGChild() || should_use_infinite_cull_rect ||
            !HasScrolledEnough(object));
     return;
   }
diff --git a/third_party/blink/renderer/core/paint/cull_rect_updater_test.cc b/third_party/blink/renderer/core/paint/cull_rect_updater_test.cc
index adab6fe..8f5f1fd5 100644
--- a/third_party/blink/renderer/core/paint/cull_rect_updater_test.cc
+++ b/third_party/blink/renderer/core/paint/cull_rect_updater_test.cc
@@ -710,10 +710,16 @@
 }
 
 TEST_P(CullRectUpdateOnPaintPropertyChangeTest, Transform) {
+  // We use infinite cull rect for small layers with non-composited transforms,
+  // so don't need to update cull rect on non-composited transform change.
   TestTargetChange("transform: translateX(10px)", "transform: translateX(20px)",
-                   false, true, false);
+                   false, false, false);
   TestTargetChange("transform: translateX(10px)", "", true, true, true);
   TestTargetChange("", "transform: translateX(10px)", true, true, true);
+  // We don't use infinite cull rect for layers with composited transforms.
+  TestTargetChange("will-change: transform; transform: translateX(10px)",
+                   "will-change: transform; transform: translateX(20px)", false,
+                   true, false);
   TestTargetChange("will-change: transform; transform: translateX(10px)",
                    "will-change: transform", false, true, false);
   TestTargetChange("will-change: transform",