summaryrefslogtreecommitdiffstats
path: root/layout/generic/nsGfxScrollFrame.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'layout/generic/nsGfxScrollFrame.cpp')
-rw-r--r--layout/generic/nsGfxScrollFrame.cpp87
1 files changed, 55 insertions, 32 deletions
diff --git a/layout/generic/nsGfxScrollFrame.cpp b/layout/generic/nsGfxScrollFrame.cpp
index 3ed3b0bb3..fcd365edf 100644
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -3031,7 +3031,6 @@ struct HoveredStateComparator
void
ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder,
- const nsRect& aDirtyRect,
const nsDisplayListSet& aLists,
bool aCreateLayer,
bool aPositioned)
@@ -3091,25 +3090,30 @@ ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder,
// 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 visible = mIsRoot && mOuter->PresContext()->IsRootContentDocument()
+ ? scrollParts[i]->GetVisualOverflowRectRelativeToParent()
+ : aBuilder->GetVisibleRect();
nsRect dirty = mIsRoot && mOuter->PresContext()->IsRootContentDocument()
? scrollParts[i]->GetVisualOverflowRectRelativeToParent()
- : aDirtyRect;
- nsDisplayListBuilder::AutoBuildingDisplayList
- buildingForChild(aBuilder, scrollParts[i],
- dirty + mOuter->GetOffsetTo(scrollParts[i]), true);
+ : aBuilder->GetDirtyRect();
// 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;
- nsDisplayListBuilder::AutoCurrentScrollbarInfoSetter
- infoSetter(aBuilder, scrollTargetId, flags, createLayer);
- nsDisplayListCollection partList;
- mOuter->BuildDisplayListForChild(
- aBuilder, scrollParts[i], dirty, partList,
- nsIFrame::DISPLAY_CHILD_FORCE_STACKING_CONTEXT);
-
+ nsDisplayListCollection partList(aBuilder);
+ {
+ nsDisplayListBuilder::AutoBuildingDisplayList
+ buildingForChild(aBuilder, mOuter,
+ visible, dirty, true);
+
+ nsDisplayListBuilder::AutoCurrentScrollbarInfoSetter
+ infoSetter(aBuilder, scrollTargetId, flags, createLayer);
+ mOuter->BuildDisplayListForChild(
+ aBuilder, scrollParts[i], partList,
+ nsIFrame::DISPLAY_CHILD_FORCE_STACKING_CONTEXT);
+ }
if (createLayer) {
appendToTopFlags |= APPEND_OWN_LAYER;
}
@@ -3117,11 +3121,19 @@ ScrollFrameHelper::AppendScrollPartsTo(nsDisplayListBuilder* aBuilder,
appendToTopFlags |= APPEND_POSITIONED;
}
+ {
+ nsDisplayListBuilder::AutoBuildingDisplayList
+ buildingForChild(aBuilder, scrollParts[i],
+ visible + mOuter->GetOffsetTo(scrollParts[i]),
+ dirty + mOuter->GetOffsetTo(scrollParts[i]), true);
+ nsDisplayListBuilder::AutoCurrentScrollbarInfoSetter
+ infoSetter(aBuilder, scrollTargetId, flags, createLayer);
// DISPLAY_CHILD_FORCE_STACKING_CONTEXT put everything into
// partList.PositionedDescendants().
::AppendToTop(aBuilder, aLists,
partList.PositionedDescendants(), scrollParts[i],
appendToTopFlags);
+ }
}
}
@@ -3246,7 +3258,6 @@ ClipListsExceptCaret(nsDisplayListCollection* aLists,
void
ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
- const nsRect& aDirtyRect,
const nsDisplayListSet& aLists)
{
if (aBuilder->IsForFrameVisibility()) {
@@ -3283,12 +3294,15 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// had dirty rects saved for them by their parent frames calling
// MarkOutOfFlowChildrenForDisplayList, so it's safe to restrict our
// dirty rect here.
- nsRect dirtyRect = aDirtyRect;
+ nsRect visibleRect = aBuilder->GetVisibleRect();
+ nsRect dirtyRect = aBuilder->GetDirtyRect();
if (!ignoringThisScrollFrame) {
+ visibleRect = visibleRect.Intersect(mScrollPort);
dirtyRect = dirtyRect.Intersect(mScrollPort);
}
- Unused << DecideScrollableLayer(aBuilder, &dirtyRect,
+ bool usingDisplayPortInvalidRect = false;
+ Unused << DecideScrollableLayer(aBuilder, &visibleRect, &dirtyRect,
/* aAllowCreateDisplayPort = */ !mIsRoot);
bool usingDisplayPort = aBuilder->IsPaintingToWindow() &&
@@ -3300,6 +3314,7 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// too much expansion in the presence of very large (bigger than the
// viewport) scroll ports.
dirtyRect = ExpandRectToNearlyVisible(dirtyRect);
+ visibleRect = dirtyRect;
}
// We put non-overlay scrollbars in their own layers when this is the root
@@ -3325,20 +3340,20 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
if (addScrollBars) {
// Add classic scrollbars.
- AppendScrollPartsTo(aBuilder, aDirtyRect, aLists,
- createLayersForScrollbars, false);
+ AppendScrollPartsTo(aBuilder, aLists, createLayersForScrollbars, false);
}
+ nsDisplayListBuilder::AutoBuildingDisplayList
+ building(aBuilder, mOuter, visibleRect, dirtyRect, aBuilder->IsAtRootOfPseudoStackingContext());
+
// Don't clip the scrolled child, and don't paint scrollbars/scrollcorner.
// The scrolled frame shouldn't have its own background/border, so we
// can just pass aLists directly.
- mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame,
- dirtyRect, aLists);
+ mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, aLists);
if (addScrollBars) {
// Add overlay scrollbars.
- AppendScrollPartsTo(aBuilder, aDirtyRect, aLists,
- createLayersForScrollbars, true);
+ AppendScrollPartsTo(aBuilder, aLists, createLayersForScrollbars, true);
}
return;
@@ -3376,8 +3391,7 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// Note that this does not apply for overlay scrollbars; those are drawn
// in the positioned-elements layer on top of everything else by the call
// to AppendScrollPartsTo(..., true) further down.
- AppendScrollPartsTo(aBuilder, aDirtyRect, aLists,
- createLayersForScrollbars, false);
+ AppendScrollPartsTo(aBuilder, aLists, createLayersForScrollbars, false);
const nsStyleDisplay* disp = mOuter->StyleDisplay();
if (disp && (disp->mWillChangeBitField & NS_STYLE_WILL_CHANGE_SCROLL)) {
@@ -3414,7 +3428,7 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
nsIScrollableFrame* sf = do_QueryFrame(mOuter);
MOZ_ASSERT(sf);
- nsDisplayListCollection scrolledContent;
+ nsDisplayListCollection scrolledContent(aBuilder);
{
// Note that setting the current scroll parent id here means that positioned children
// of this scroll info layer will pick up the scroll info layer as their scroll handoff
@@ -3501,12 +3515,15 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// pixels.
// If there is no display port, we don't need this because the clip
// from the scroll port is still applied.
- scrolledRectClip = scrolledRectClip.Intersect(dirtyRect);
+ scrolledRectClip = scrolledRectClip.Intersect(visibleRect);
}
scrolledRectClipState.ClipContainingBlockDescendants(
scrolledRectClip + aBuilder->ToReferenceFrame(mOuter));
- mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, dirtyRect, scrolledContent);
+ nsDisplayListBuilder::AutoBuildingDisplayList
+ building(aBuilder, mOuter, visibleRect, dirtyRect, aBuilder->IsAtRootOfPseudoStackingContext());
+
+ mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, scrolledContent);
}
if (contentBoxClipForNonCaretContent) {
@@ -3558,7 +3575,8 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// recompute the current animated geometry root if needed.
// It's too late to change the dirty rect so pass a copy.
nsRect copyOfDirtyRect = dirtyRect;
- Unused << DecideScrollableLayer(aBuilder, &copyOfDirtyRect,
+ nsRect copyOfVisibleRect = visibleRect;
+ Unused << DecideScrollableLayer(aBuilder, &copyOfVisibleRect, &copyOfDirtyRect,
/* aAllowCreateDisplayPort = */ false);
}
}
@@ -3593,13 +3611,14 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
}
}
// Now display overlay scrollbars and the resizer, if we have one.
- AppendScrollPartsTo(aBuilder, aDirtyRect, scrolledContent,
- createLayersForScrollbars, true);
+ AppendScrollPartsTo(aBuilder, scrolledContent, createLayersForScrollbars, true);
+
scrolledContent.MoveTo(aLists);
}
bool
ScrollFrameHelper::DecideScrollableLayer(nsDisplayListBuilder* aBuilder,
+ nsRect* aVisibleRect,
nsRect* aDirtyRect,
bool aAllowCreateDisplayPort)
{
@@ -3615,16 +3634,16 @@ ScrollFrameHelper::DecideScrollableLayer(nsDisplayListBuilder* aBuilder,
if (aAllowCreateDisplayPort) {
nsLayoutUtils::MaybeCreateDisplayPort(*aBuilder, mOuter);
- nsRect displayportBase = *aDirtyRect;
+ nsRect displayportBase = *aVisibleRect;
nsPresContext* pc = mOuter->PresContext();
if (mIsRoot && (pc->IsRootContentDocument() || !pc->GetParentPresContext())) {
displayportBase =
nsRect(nsPoint(0, 0), nsLayoutUtils::CalculateCompositionSizeForFrame(mOuter));
} else {
- // Make the displayport base equal to the dirty rect restricted to
+ // Make the displayport base equal to the visible rect restricted to
// the scrollport and the root composition bounds, relative to the
// scrollport.
- displayportBase = aDirtyRect->Intersect(mScrollPort);
+ displayportBase = aVisibleRect->Intersect(mScrollPort);
// Only restrict to the root composition bounds if necessary,
// as the required coordinate transformation is expensive.
@@ -3687,12 +3706,15 @@ ScrollFrameHelper::DecideScrollableLayer(nsDisplayListBuilder* aBuilder,
if (usingDisplayPort) {
// Override the dirty rectangle if the displayport has been set.
+ *aVisibleRect = displayPort;
*aDirtyRect = displayPort;
} else if (mIsRoot) {
// The displayPort getter takes care of adjusting for resolution. So if
// we have resolution but no displayPort then we need to adjust for
// resolution here.
nsIPresShell* presShell = mOuter->PresContext()->PresShell();
+ *aVisibleRect = aVisibleRect->RemoveResolution(
+ presShell->ScaleToResolution() ? presShell->GetResolution () : 1.0f);
*aDirtyRect = aDirtyRect->RemoveResolution(
presShell->ScaleToResolution() ? presShell->GetResolution () : 1.0f);
}
@@ -6175,3 +6197,4 @@ ScrollFrameHelper::UsesContainerScrolling() const
}
return false;
}
+