Bug 1359868 - Try to pre-render offscreen portions of scrollbar thumbs. r=mstange
authorBotond Ballo <botond@mozilla.com>
Mon, 01 May 2017 20:32:07 -0400
changeset 406363 ef01a708f156b3a9c8c9f7d46959fe61571a6692
parent 406362 6e2858fb7826109d65736e6a14e917fcca59addd
child 406364 57bb4f9df629df1abb0e6c2dd36270be0e685977
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1359868
milestone55.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 1359868 - Try to pre-render offscreen portions of scrollbar thumbs. r=mstange MozReview-Commit-ID: K3TPswpjh3O
layout/generic/nsGfxScrollFrame.cpp
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -3088,23 +3088,43 @@ ScrollFrameHelper::AppendScrollPartsTo(n
       flags |= nsDisplayOwnLayer::VERTICAL_SCROLLBAR;
       appendToTopFlags |= APPEND_SCROLLBAR_CONTAINER;
     }
     if (scrollParts[i] == mHScrollbarBox) {
       flags |= nsDisplayOwnLayer::HORIZONTAL_SCROLLBAR;
       appendToTopFlags |= APPEND_SCROLLBAR_CONTAINER;
     }
 
-    // The display port doesn't necessarily include the scrollbars, so just
-    // include all of the scrollbars if we are in a RCD-RSF. We only do
-    // this for the root scrollframe of the root content document, which is
-    // zoomable, and where the scrollbar sizes are bounded by the widget.
-    nsRect dirty = mIsRoot && mOuter->PresContext()->IsRootContentDocument()
-                   ? scrollParts[i]->GetVisualOverflowRectRelativeToParent()
-                   : aDirtyRect;
+    // The display port doesn't necessarily include the scrollbars.
+    bool thumbGetsLayer = (scrollTargetId != FrameMetrics::NULL_SCROLL_ID);
+    bool isRcdRsf = mIsRoot && mOuter->PresContext()->IsRootContentDocument();
+    nsRect dirty = aDirtyRect;
+    if (isRcdRsf || thumbGetsLayer) {
+      nsRect overflow = scrollParts[i]->GetVisualOverflowRectRelativeToParent();
+      if (isRcdRsf) {
+        // For the root content document's root scroll frame (RCD-RSF), include
+        // all of the scrollbars. We only do this for the RCD-RSF, which is
+        // zoomable, and where the scrollbar sizes are bounded by the widget.
+        dirty = overflow;
+      } else {
+        // For subframes, we still try to prerender parts of the scrollbar that
+        // are not currently visible, because they might be brought into view
+        // by async scrolling, but we bound the area to render by the size of
+        // the root reference frame (because subframe scrollbars can be
+        // arbitrary large).
+        nsSize refSize = aBuilder->RootReferenceFrame()->GetSize();
+        gfxSize scale = nsLayoutUtils::GetTransformToAncestorScale(mOuter);
+        if (scale.width != 0 && scale.height != 0) {
+          refSize.width /= scale.width;
+          refSize.height /= scale.height;
+        }
+        dirty = nsLayoutUtils::ComputePartialPrerenderArea(dirty, overflow, refSize);
+      }
+    }
+
     nsDisplayListBuilder::AutoBuildingDisplayList
       buildingForChild(aBuilder, scrollParts[i],
                        dirty + mOuter->GetOffsetTo(scrollParts[i]), true);
 
     // Always create layers for overlay scrollbars so that we don't create a
     // giant layer covering the whole scrollport if both scrollbars are visible.
     bool isOverlayScrollbar = (flags != 0) && overlayScrollbars;
     bool createLayer = aCreateLayer || isOverlayScrollbar ||