Bug 1298218 - Save and restore the combined clip for the "top layer". r?tnikkel
MozReview-Commit-ID: IRfB85gVyWB
--- a/layout/generic/ViewportFrame.cpp
+++ b/layout/generic/ViewportFrame.cpp
@@ -102,18 +102,25 @@ BuildDisplayListForTopLayerFrame(nsDispl
{
nsRect dirty;
DisplayListClipState::AutoClipMultiple clipState(aBuilder);
nsDisplayListBuilder::AutoCurrentActiveScrolledRootSetter asrSetter(aBuilder);
nsDisplayListBuilder::OutOfFlowDisplayData*
savedOutOfFlowData = nsDisplayListBuilder::GetOutOfFlowData(aFrame);
if (savedOutOfFlowData) {
dirty = savedOutOfFlowData->mDirtyRect;
+ // This function is called after we've finished building display items for
+ // the root scroll frame. That means that the content clip from the root
+ // scroll frame is no longer on aBuilder. However, we need to make sure
+ // that the display items we build in this function have finite clipped
+ // bounds with respect to the root ASR, so we restore the *combined clip*
+ // that we saved earlier. The combined clip will include the clip from the
+ // root scroll frame.
clipState.SetClipChainForContainingBlockDescendants(
- savedOutOfFlowData->mContainingBlockClipChain);
+ savedOutOfFlowData->mCombinedClipChain);
clipState.ClipContainingBlockDescendantsExtra(
dirty + aBuilder->ToReferenceFrame(aFrame), nullptr);
asrSetter.SetCurrentActiveScrolledRoot(
savedOutOfFlowData->mContainingBlockActiveScrolledRoot);
}
nsDisplayList list;
aFrame->BuildDisplayListForStackingContext(aBuilder, dirty, &list);
aList->AppendToTop(&list);
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -1046,18 +1046,19 @@ void nsDisplayListBuilder::MarkOutOfFlow
!(aFrame->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)) {
return;
}
// mClipState.GetClipChainForContainingBlockDescendants can return pointers
// to objects on the stack, so we need to clone the chain.
const DisplayItemClipChain* clipChain =
CopyWholeChain(mClipState.GetClipChainForContainingBlockDescendants());
+ const DisplayItemClipChain* combinedClipChain = mClipState.GetCurrentCombinedClipChain(this);
const ActiveScrolledRoot* asr = mCurrentActiveScrolledRoot;
- OutOfFlowDisplayData* data = new OutOfFlowDisplayData(clipChain, asr, dirty);
+ OutOfFlowDisplayData* data = new OutOfFlowDisplayData(clipChain, combinedClipChain, asr, dirty);
aFrame->Properties().Set(nsDisplayListBuilder::OutOfFlowDisplayDataProperty(), data);
MarkFrameForDisplay(aFrame, aDirtyFrame);
}
static void UnmarkFrameForDisplay(nsIFrame* aFrame) {
nsPresContext* presContext = aFrame->PresContext();
presContext->PropertyTable()->
@@ -1270,19 +1271,20 @@ nsDisplayListBuilder::MarkFramesForDispl
NS_ASSERTION(CurrentPresShellState()->mPresShell ==
aDirtyFrame->PresContext()->PresShell(),
"Presshell mismatch");
MOZ_ASSERT(!CurrentPresShellState()->mFixedBackgroundDisplayData,
"already traversed this presshell's root frame?");
const DisplayItemClipChain* clipChain =
CopyWholeChain(mClipState.GetClipChainForContainingBlockDescendants());
+ const DisplayItemClipChain* combinedClipChain = mClipState.GetCurrentCombinedClipChain(this);
const ActiveScrolledRoot* asr = mCurrentActiveScrolledRoot;
CurrentPresShellState()->mFixedBackgroundDisplayData.emplace(
- clipChain, asr, aDirtyRect);
+ clipChain, combinedClipChain, asr, aDirtyRect);
}
}
/**
* Mark all preserve-3d children with
* NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO to make sure
* nsFrame::BuildDisplayListForChild() would visit them. Also compute
* dirty rect for preserve-3d children.
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -1206,23 +1206,26 @@ public:
}
// Helpers for tables
nsDisplayTableItem* GetCurrentTableItem() { return mCurrentTableItem; }
void SetCurrentTableItem(nsDisplayTableItem* aTableItem) { mCurrentTableItem = aTableItem; }
struct OutOfFlowDisplayData {
OutOfFlowDisplayData(const DisplayItemClipChain* aContainingBlockClipChain,
+ const DisplayItemClipChain* aCombinedClipChain,
const ActiveScrolledRoot* aContainingBlockActiveScrolledRoot,
const nsRect &aDirtyRect)
: mContainingBlockClipChain(aContainingBlockClipChain)
+ , mCombinedClipChain(aCombinedClipChain)
, mContainingBlockActiveScrolledRoot(aContainingBlockActiveScrolledRoot)
, mDirtyRect(aDirtyRect)
{}
const DisplayItemClipChain* mContainingBlockClipChain;
+ const DisplayItemClipChain* mCombinedClipChain; // only necessary for the special case of top layer
const ActiveScrolledRoot* mContainingBlockActiveScrolledRoot;
nsRect mDirtyRect;
};
NS_DECLARE_FRAME_PROPERTY_DELETABLE(OutOfFlowDisplayDataProperty,
OutOfFlowDisplayData)
static OutOfFlowDisplayData* GetOutOfFlowData(nsIFrame* aFrame)