зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1404181 - Part 23: Only rebuild items within a displayport when the displayport changes, rather than rebuilding the whole document. r=mstange
MozReview-Commit-ID: IYEPCKSvtBY --HG-- extra : rebase_source : f6b65a88dcd82b7828af371874bf3adde2af688f
This commit is contained in:
Родитель
3fa03bb34e
Коммит
4dc75f2d67
|
@ -474,6 +474,9 @@ nsDOMWindowUtils::SetDisplayPortForElement(float aXPx, float aYPx,
|
|||
}
|
||||
}
|
||||
|
||||
nsLayoutUtils::InvalidateForDisplayPortChange(content, !!currentData,
|
||||
currentData ? currentData->mRect : nsRect(), displayport);
|
||||
|
||||
nsIFrame* rootFrame = presShell->FrameManager()->GetRootFrame();
|
||||
if (rootFrame) {
|
||||
rootFrame->SchedulePaint();
|
||||
|
|
|
@ -1375,6 +1375,54 @@ nsLayoutUtils::GetDisplayPortForVisibilityTesting(
|
|||
return usingDisplayPort;
|
||||
}
|
||||
|
||||
void
|
||||
nsLayoutUtils::InvalidateForDisplayPortChange(nsIContent* aContent,
|
||||
bool aHadDisplayPort,
|
||||
const nsRect& aOldDisplayPort,
|
||||
const nsRect& aNewDisplayPort,
|
||||
RepaintMode aRepaintMode)
|
||||
{
|
||||
if (aRepaintMode != RepaintMode::Repaint) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool changed = !aHadDisplayPort ||
|
||||
!aOldDisplayPort.IsEqualEdges(aNewDisplayPort);
|
||||
|
||||
nsIFrame* frame = GetScrollFrameFromContent(aContent);
|
||||
if (frame) {
|
||||
frame = do_QueryFrame(frame->GetScrollTargetFrame());
|
||||
}
|
||||
|
||||
if (changed && frame) {
|
||||
// It is important to call SchedulePaint on the same frame that we set the dirty
|
||||
// rect properties on so we can find the frame later to remove the properties.
|
||||
frame->SchedulePaint();
|
||||
|
||||
nsIFrame* displayRoot = nsLayoutUtils::GetDisplayRootFrame(frame);
|
||||
RetainedDisplayListBuilder* retainedBuilder =
|
||||
displayRoot->GetProperty(RetainedDisplayListBuilder::Cached());
|
||||
if (retainedBuilder) {
|
||||
nsRect* rect =
|
||||
frame->GetProperty(nsDisplayListBuilder::DisplayListBuildingDisplayPortRect());
|
||||
if (!rect) {
|
||||
rect = new nsRect();
|
||||
frame->SetProperty(nsDisplayListBuilder::DisplayListBuildingDisplayPortRect(), rect);
|
||||
frame->SetHasOverrideDirtyRegion(true);
|
||||
}
|
||||
if (aHadDisplayPort) {
|
||||
// We only need to build a display list for any new areas added
|
||||
nsRegion newRegion(aNewDisplayPort);
|
||||
newRegion.SubOut(aOldDisplayPort);
|
||||
rect->UnionRect(*rect, newRegion.GetBounds());
|
||||
} else {
|
||||
rect->UnionRect(*rect, aNewDisplayPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
nsLayoutUtils::SetDisplayPortMargins(nsIContent* aContent,
|
||||
nsIPresShell* aPresShell,
|
||||
|
@ -1403,9 +1451,6 @@ nsLayoutUtils::SetDisplayPortMargins(nsIContent* aContent,
|
|||
DebugOnly<bool> hasDisplayPort = GetHighResolutionDisplayPort(aContent, &newDisplayPort);
|
||||
MOZ_ASSERT(hasDisplayPort);
|
||||
|
||||
bool changed = !hadDisplayPort ||
|
||||
!oldDisplayPort.IsEqualEdges(newDisplayPort);
|
||||
|
||||
if (gfxPrefs::LayoutUseContainersForRootFrames()) {
|
||||
nsIFrame* rootScrollFrame = aPresShell->GetRootScrollFrame();
|
||||
if (rootScrollFrame &&
|
||||
|
@ -1419,12 +1464,8 @@ nsLayoutUtils::SetDisplayPortMargins(nsIContent* aContent,
|
|||
}
|
||||
}
|
||||
|
||||
if (changed && aRepaintMode == RepaintMode::Repaint) {
|
||||
nsIFrame* frame = aContent->GetPrimaryFrame();
|
||||
if (frame) {
|
||||
frame->SchedulePaint();
|
||||
}
|
||||
}
|
||||
InvalidateForDisplayPortChange(aContent, hadDisplayPort, oldDisplayPort,
|
||||
newDisplayPort, aRepaintMode);
|
||||
|
||||
nsIFrame* frame = GetScrollFrameFromContent(aContent);
|
||||
nsIScrollableFrame* scrollableFrame = frame ? frame->GetScrollTargetFrame() : nullptr;
|
||||
|
@ -3723,7 +3764,7 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
|||
MaybeCreateDisplayPortInFirstScrollFrameEncountered(aFrame, builder);
|
||||
}
|
||||
|
||||
nsRect dirtyRect = visibleRegion.GetBounds();
|
||||
nsRect visibleRect = visibleRegion.GetBounds();
|
||||
|
||||
{
|
||||
AUTO_PROFILER_LABEL("nsLayoutUtils::PaintFrame:BuildDisplayList",
|
||||
|
@ -3760,7 +3801,7 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
|||
|
||||
nsDisplayListBuilder::AutoCurrentScrollParentIdSetter idSetter(&builder, id);
|
||||
|
||||
builder.SetVisibleRect(dirtyRect);
|
||||
builder.SetVisibleRect(visibleRect);
|
||||
builder.SetIsBuilding(true);
|
||||
|
||||
const bool paintedPreviously =
|
||||
|
@ -3777,7 +3818,7 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
|||
if (!merged) {
|
||||
list.DeleteAll(&builder);
|
||||
builder.EnterPresShell(aFrame);
|
||||
builder.SetDirtyRect(dirtyRect);
|
||||
builder.SetDirtyRect(visibleRect);
|
||||
builder.ClearWindowDraggingRegion();
|
||||
aFrame->BuildDisplayListForStackingContext(&builder, &list);
|
||||
AddExtraBackgroundItems(builder, list, aFrame, canvasArea, visibleRegion, aBackstop);
|
||||
|
@ -3838,7 +3879,7 @@ nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
|
|||
}
|
||||
#endif
|
||||
*ss << nsPrintfCString("Painting --- before optimization (dirty %d,%d,%d,%d):\n",
|
||||
dirtyRect.x, dirtyRect.y, dirtyRect.width, dirtyRect.height).get();
|
||||
visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height).get();
|
||||
nsFrame::PrintDisplayList(&builder, list, *ss, gfxEnv::DumpPaintToFile());
|
||||
|
||||
if (gfxEnv::DumpPaint() || gfxEnv::DumpPaintItems()) {
|
||||
|
|
|
@ -252,6 +252,15 @@ public:
|
|||
DoNotRepaint
|
||||
};
|
||||
|
||||
/**
|
||||
* Invalidate for displayport change.
|
||||
*/
|
||||
static void InvalidateForDisplayPortChange(nsIContent* aContent,
|
||||
bool aHadDisplayPort,
|
||||
const nsRect& aOldDisplayPort,
|
||||
const nsRect& aNewDisplayPort,
|
||||
RepaintMode aRepaintMode = RepaintMode::Repaint);
|
||||
|
||||
/**
|
||||
* Set the display port margins for a content element to be used with a
|
||||
* display port base (see SetDisplayPortBase()).
|
||||
|
|
|
@ -3302,6 +3302,9 @@ ScrollFrameHelper::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
|||
}
|
||||
}
|
||||
|
||||
// It's safe to get this value before the DecideScrollableLayer call below
|
||||
// because that call cannot create a displayport for root scroll frames,
|
||||
// and hence it cannot create an ignore scroll frame.
|
||||
bool ignoringThisScrollFrame =
|
||||
aBuilder->GetIgnoreScrollFrame() == mOuter || IsIgnoringViewportClipping();
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче