Bug 1241917 - Restrict subframe's displayport base to root composition bounds. r=tn
authorJamie Nicol <jnicol@mozilla.com>
Thu, 04 Feb 2016 17:53:56 +0000
changeset 319565 046c7007ac8e111e26c05d5de5190e3b6d29647a
parent 319564 2ada62724f2af8b0d6c104e3bd249ab28d021d2f
child 319566 0dc0dc424f066d349b7624f6e88ad42c98bec5d8
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstn
bugs1241917
milestone47.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1241917 - Restrict subframe's displayport base to root composition bounds. r=tn Previously displayport bases were computed as the intersection of the scrollport with the dirtyrect. However the dirtyrect covers what is rendered, and with displayports what we render can be much larger than what is visible. With displayport bases intended to represent what was visible, this was a problem. By restricting them to the root composition size this makes them more closely match what is visible. To do this more properly we'd want to intersect the dirtyrect with the scroll clip of every ancestor scroll frame, not just the root composition bounds.
layout/generic/nsGfxScrollFrame.cpp
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -3341,19 +3341,42 @@ ScrollFrameHelper::DecideScrollableLayer
 
     if (aAllowCreateDisplayPort) {
       nsRect displayportBase = *aDirtyRect;
       nsPresContext* pc = mOuter->PresContext();
       if (mIsRoot && (pc->IsRootContentDocument() || !pc->GetParentPresContext())) {
         displayportBase =
           nsRect(nsPoint(0, 0), nsLayoutUtils::CalculateCompositionSizeForFrame(mOuter));
       } else {
-        // Restrict the dirty rect to the scrollport, and make it relative to the
-        // scrollport for the displayport base.
+        // Make the displayport base equal to the dirty rect restricted to
+        // the scrollport and the root composition bounds, relative to the
+        // scrollport.
         displayportBase = aDirtyRect->Intersect(mScrollPort);
+
+        const nsPresContext* rootPresContext =
+          pc->GetToplevelContentDocumentPresContext();
+        if (!rootPresContext) {
+          rootPresContext = pc->GetRootPresContext();
+        }
+        if (rootPresContext) {
+          const nsIPresShell* const rootPresShell = rootPresContext->PresShell();
+          nsIFrame* rootFrame = rootPresShell->GetRootScrollFrame();
+          if (!rootFrame) {
+            rootFrame = rootPresShell->GetRootFrame();
+          }
+          if (rootFrame) {
+            nsRect rootCompBounds =
+              nsRect(nsPoint(0, 0), nsLayoutUtils::CalculateCompositionSizeForFrame(rootFrame));
+
+            nsLayoutUtils::TransformRect(rootFrame, mOuter, rootCompBounds);
+
+            displayportBase = displayportBase.Intersect(rootCompBounds);
+          }
+        }
+
         displayportBase -= mScrollPort.TopLeft();
       }
 
       // Provide the value of the display port base rect, and possibly create a
       // display port if there isn't one already.
       nsLayoutUtils::MaybeCreateDisplayPort(*aBuilder, mOuter, displayportBase);
     }