From e509fc4068a851875067f8f043bffb2aaef9e561 Mon Sep 17 00:00:00 2001 From: Botond Ballo Date: Mon, 1 May 2017 20:32:07 -0400 Subject: [PATCH] Bug 1359868 - Try to pre-render offscreen portions of scrollbar thumbs. r=mstange MozReview-Commit-ID: K3TPswpjh3O --- layout/generic/nsGfxScrollFrame.cpp | 34 +++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp index 90c6284f00fa..753831de30b4 100644 --- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -3093,13 +3093,33 @@ ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder, 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);