Bug 1363219 - Try harder to pre-render offscreen portions of scrollbar thumbs. r=mstange
authorBotond Ballo <botond@mozilla.com>
Mon, 08 May 2017 18:28:26 -0400
changeset 358780 f74ec590a5343f603c2e070afa25743dd15df43d
parent 358779 1f09b8e255ddf965d62a2cc0086ce08ed5e86ea9
child 358781 1dc0fc082830cc3efb1fb889e752e83ecbe56e0f
push id31838
push userkwierso@gmail.com
push dateWed, 17 May 2017 20:32:10 +0000
treeherdermozilla-central@b133ec74e3d0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1363219, 1359868
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 1363219 - Try harder to pre-render offscreen portions of scrollbar thumbs. r=mstange In bug 1359868 we started to do this, but we bounded the pre-render region for the entire scrollbar by the widget bounds, which is not helpful for tall scrollframes with short thumbs. This time, we are bounding the pre-render region of the thumb only, so a small thumb will always be completely painted. MozReview-Commit-ID: 5LuP5Lfahdm
layout/generic/nsGfxScrollFrame.cpp
layout/xul/nsSliderFrame.cpp
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -3088,43 +3088,23 @@ 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.
-    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);
-      }
-    }
-
+    // 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;
     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 ||
--- a/layout/xul/nsSliderFrame.cpp
+++ b/layout/xul/nsSliderFrame.cpp
@@ -406,19 +406,29 @@ nsSliderFrame::BuildDisplayListForChildr
                     scrollPortOrigin;
       CSSCoord sliderTrackStart = NSAppUnitsToFloatPixels(
           isHorizontal ? sliderTrack.x : sliderTrack.y, appUnitsPerCss);
       CSSCoord sliderTrackLength = NSAppUnitsToFloatPixels(
           isHorizontal ? sliderTrack.width : sliderTrack.height, appUnitsPerCss);
       CSSCoord thumbStart = NSAppUnitsToFloatPixels(
           isHorizontal ? thumbRect.x : thumbRect.y, appUnitsPerCss);
 
+      nsRect overflow = thumb->GetVisualOverflowRectRelativeToParent();
+      nsSize refSize = aBuilder->RootReferenceFrame()->GetSize();
+      gfxSize scale = nsLayoutUtils::GetTransformToAncestorScale(thumb);
+      if (scale.width != 0 && scale.height != 0) {
+        refSize.width /= scale.width;
+        refSize.height /= scale.height;
+      }
+      nsRect dirty = aDirtyRect.Intersect(thumbRect);
+      dirty = nsLayoutUtils::ComputePartialPrerenderArea(aDirtyRect, overflow, refSize);
+
       nsDisplayListBuilder::AutoContainerASRTracker contASRTracker(aBuilder);
       nsDisplayListCollection tempLists;
-      nsBoxFrame::BuildDisplayListForChildren(aBuilder, aDirtyRect, tempLists);
+      nsBoxFrame::BuildDisplayListForChildren(aBuilder, dirty, tempLists);
 
       // This is a bit of a hack. Collect up all descendant display items
       // and merge them into a single Content() list.
       nsDisplayList masterList;
       masterList.AppendToTop(tempLists.BorderBackground());
       masterList.AppendToTop(tempLists.BlockBorderBackgrounds());
       masterList.AppendToTop(tempLists.Floats());
       masterList.AppendToTop(tempLists.Content());