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
--- 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());