Bug 1429932 - Part 7: Restrict dirty regions in ComputeRebuildRegion to the overflow area of the current frame so that we discard invalidations that aren't visible. r=miko
authorMatt Woodrow <mwoodrow@mozilla.com>
Fri, 12 Jan 2018 11:51:08 +1300
changeset 752957 24cf388d5d5b85e17a7cacaa53e2956cda20aff4
parent 752956 8f7a4df5efcc9becd605e60dfe7c61002264a32c
child 752958 ee3062043923076fceffbb61f85acc6d10339605
push id98429
push usermak77@bonardo.net
push dateFri, 09 Feb 2018 10:14:12 +0000
reviewersmiko
bugs1429932
milestone60.0a1
Bug 1429932 - Part 7: Restrict dirty regions in ComputeRebuildRegion to the overflow area of the current frame so that we discard invalidations that aren't visible. r=miko MozReview-Commit-ID: BJ5Ud7c9ofk
layout/painting/RetainedDisplayListBuilder.cpp
--- a/layout/painting/RetainedDisplayListBuilder.cpp
+++ b/layout/painting/RetainedDisplayListBuilder.cpp
@@ -795,16 +795,20 @@ ProcessFrame(nsIFrame* aFrame, nsDisplay
 
     // Convert 'aOverflow' into the coordinate space of the nearest stacking context
     // or display port ancestor and update 'currentFrame' to point to that frame.
     aOverflow = nsLayoutUtils::TransformFrameRectToAncestor(currentFrame, aOverflow, aStopAtFrame,
                                                            nullptr, nullptr,
                                                            /* aStopAtStackingContextAndDisplayPortAndOOFFrame = */ true,
                                                            &currentFrame);
     MOZ_ASSERT(currentFrame);
+    aOverflow.IntersectRect(aOverflow, currentFrame->GetVisualOverflowRectRelativeToSelf());
+    if (aOverflow.IsEmpty()) {
+      break;
+    }
 
     if (nsLayoutUtils::FrameHasDisplayPort(currentFrame)) {
       CRR_LOG("Frame belongs to displayport frame %p\n", currentFrame);
       nsIScrollableFrame* sf = do_QueryFrame(currentFrame);
       MOZ_ASSERT(sf);
       nsRect displayPort;
       DebugOnly<bool> hasDisplayPort =
         nsLayoutUtils::GetDisplayPort(currentFrame->GetContent(), &displayPort,
@@ -951,28 +955,30 @@ RetainedDisplayListBuilder::ComputeRebui
     // might have an empty overflow rect.
     if (f == mBuilder.GetCaretFrame()) {
       overflow.UnionRect(overflow, mBuilder.GetCaretRect());
     }
 
     ProcessFrame(f, mBuilder, &agr, overflow, mBuilder.RootReferenceFrame(),
                  aOutFramesWithProps, true);
 
-    aOutDirty->UnionRect(*aOutDirty, overflow);
-    CRR_LOG("Adding area to root draw area: %d %d %d %d\n",
-            overflow.x, overflow.y, overflow.width, overflow.height);
+    if (!overflow.IsEmpty()) {
+      aOutDirty->UnionRect(*aOutDirty, overflow);
+      CRR_LOG("Adding area to root draw area: %d %d %d %d\n",
+              overflow.x, overflow.y, overflow.width, overflow.height);
 
-    // If we get changed frames from multiple AGRS, then just give up as it gets really complex to
-    // track which items would need to be marked in MarkFramesForDifferentAGR.
-    if (!*aOutModifiedAGR) {
-      CRR_LOG("Setting %p as root stacking context AGR\n", agr);
-      *aOutModifiedAGR = agr;
-    } else if (agr && *aOutModifiedAGR != agr) {
-      CRR_LOG("Found multiple AGRs in root stacking context, giving up\n");
-      return false;
+      // If we get changed frames from multiple AGRS, then just give up as it gets really complex to
+      // track which items would need to be marked in MarkFramesForDifferentAGR.
+      if (!*aOutModifiedAGR) {
+        CRR_LOG("Setting %p as root stacking context AGR\n", agr);
+        *aOutModifiedAGR = agr;
+      } else if (agr && *aOutModifiedAGR != agr) {
+        CRR_LOG("Found multiple AGRs in root stacking context, giving up\n");
+        return false;
+      }
     }
   }
 
   return true;
 }
 
 /*
  * A simple early exit heuristic to avoid slow partial display list rebuilds.