Bug 1411468 - Make display marker able to cross documents. r=mattwoodrow

MozReview-Commit-ID: GuHNVxWFuLm
This commit is contained in:
Ethan Lin 2017-10-25 18:10:04 +08:00
Родитель 6051f691bf
Коммит d79d047899
4 изменённых файлов: 19 добавлений и 15 удалений

Просмотреть файл

@ -849,7 +849,7 @@ nsSimplePageSequenceFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
visible - child->GetPosition(),
aBuilder->IsAtRootOfPseudoStackingContext());
child->BuildDisplayListForStackingContext(aBuilder, &content);
aBuilder->ResetMarkedFramesForDisplayList();
aBuilder->ResetMarkedFramesForDisplayList(this);
}
child = child->GetNextSibling();
}

Просмотреть файл

@ -112,7 +112,7 @@ RetainedDisplayListBuilder::PreProcessDisplayList(nsDisplayList* aList,
// to the common AGR (of both the existing item and the invalidated
// frame) and determine if they can ever intersect.
if (aAGR && i->GetAnimatedGeometryRoot()->GetAsyncAGR() != aAGR) {
mBuilder.MarkFrameForDisplayIfVisible(f);
mBuilder.MarkFrameForDisplayIfVisible(f, mBuilder.RootReferenceFrame());
}
// TODO: This is here because we sometimes reuse the previous display list
@ -632,7 +632,7 @@ RetainedDisplayListBuilder::ComputeRebuildRegion(nsTArray<nsIFrame*>& aModifiedF
// we need to keep bubbling up to the next stacking context.
if (currentFrame != mBuilder.RootReferenceFrame() &&
currentFrame->HasDisplayItems()) {
mBuilder.MarkFrameForDisplayIfVisible(currentFrame);
mBuilder.MarkFrameForDisplayIfVisible(currentFrame, mBuilder.RootReferenceFrame());
// Store the stacking context relative dirty area such
// that display list building will pick it up when it

Просмотреть файл

@ -1006,7 +1006,7 @@ nsDisplayListBuilder::MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFra
{
mFramesMarkedForDisplay.AppendElement(aFrame);
for (nsIFrame* f = aFrame; f;
f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) {
f = nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(f)) {
if (f->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO)
return;
f->AddStateBits(NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO);
@ -1022,7 +1022,7 @@ nsDisplayListBuilder::MarkFrameForDisplayIfVisible(nsIFrame* aFrame, nsIFrame* a
{
mFramesMarkedForDisplay.AppendElement(aFrame);
for (nsIFrame* f = aFrame; f;
f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) {
f = nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(f)) {
if (f->ForceDescendIntoIfVisible())
return;
f->SetForceDescendIntoIfVisible(true);
@ -1176,16 +1176,20 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
MarkFrameForDisplay(aFrame, aDirtyFrame);
}
static void UnmarkFrameForDisplay(nsIFrame* aFrame) {
static void UnmarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame) {
aFrame->DeleteProperty(nsDisplayListBuilder::OutOfFlowDisplayDataProperty());
for (nsIFrame* f = aFrame; f;
f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) {
f = nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(f)) {
if (!(f->GetStateBits() & NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO) &&
!f->ForceDescendIntoIfVisible())
return;
f->RemoveStateBits(NS_FRAME_FORCE_DISPLAY_LIST_DESCEND_INTO);
f->SetForceDescendIntoIfVisible(false);
if (f == aStopAtFrame) {
// we've reached a frame that we know will be painted, so we can stop.
break;
}
}
}
@ -1272,7 +1276,7 @@ nsDisplayListBuilder::EnterPresShell(nsIFrame* aReferenceFrame,
// and possibly end up with an extra nsDisplaySolidColor item.
nsCanvasFrame* canvasFrame = do_QueryFrame(sf->GetScrolledFrame());
if (canvasFrame) {
MarkFrameForDisplayIfVisible(canvasFrame);
MarkFrameForDisplayIfVisible(canvasFrame, aReferenceFrame);
}
}
@ -1302,7 +1306,7 @@ nsDisplayListBuilder::EnterPresShell(nsIFrame* aReferenceFrame,
RefPtr<nsCaret> caret = state->mPresShell->GetCaret();
state->mCaretFrame = caret->GetPaintGeometry(&state->mCaretRect);
if (state->mCaretFrame) {
MarkFrameForDisplay(state->mCaretFrame, nullptr);
MarkFrameForDisplay(state->mCaretFrame, aReferenceFrame);
}
nsPresContext* pc = aReferenceFrame->PresContext();
@ -1354,7 +1358,7 @@ nsDisplayListBuilder::LeavePresShell(nsIFrame* aReferenceFrame, nsDisplayList* a
}
}
ResetMarkedFramesForDisplayList();
ResetMarkedFramesForDisplayList(aReferenceFrame);
mPresShellStates.SetLength(mPresShellStates.Length() - 1);
if (!mPresShellStates.IsEmpty()) {
@ -1391,13 +1395,13 @@ nsDisplayListBuilder::FreeClipChains()
}
void
nsDisplayListBuilder::ResetMarkedFramesForDisplayList()
nsDisplayListBuilder::ResetMarkedFramesForDisplayList(nsIFrame* aReferenceFrame)
{
// Unmark and pop off the frames marked for display in this pres shell.
uint32_t firstFrameForShell = CurrentPresShellState()->mFirstFrameMarkedForDisplay;
for (uint32_t i = firstFrameForShell;
i < mFramesMarkedForDisplay.Length(); ++i) {
UnmarkFrameForDisplay(mFramesMarkedForDisplay[i]);
UnmarkFrameForDisplay(mFramesMarkedForDisplay[i], aReferenceFrame);
}
mFramesMarkedForDisplay.SetLength(firstFrameForShell);
}

Просмотреть файл

@ -758,7 +758,7 @@ public:
* ResetMarkedFramesForDisplayList to make sure that the results of
* MarkFramesForDisplayList do not carry over between batches.
*/
void ResetMarkedFramesForDisplayList();
void ResetMarkedFramesForDisplayList(nsIFrame* aReferenceFrame);
/**
* Notify the display list builder that we're leaving a presshell.
*/
@ -831,8 +831,8 @@ public:
*/
void MarkFramesForDisplayList(nsIFrame* aDirtyFrame,
const nsFrameList& aFrames);
void MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame = nullptr);
void MarkFrameForDisplayIfVisible(nsIFrame* aFrame, nsIFrame* aStopAtFrame = nullptr);
void MarkFrameForDisplay(nsIFrame* aFrame, nsIFrame* aStopAtFrame);
void MarkFrameForDisplayIfVisible(nsIFrame* aFrame, nsIFrame* aStopAtFrame);
void ClearFixedBackgroundDisplayData();
/**