зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1416065 - Ensure that override dirty rects are properly removed from frames r=mattwoodrow
MozReview-Commit-ID: 8uLgDFxl5MV --HG-- extra : rebase_source : f8b1202e068b448499ebe470c9d9151715cb1419
This commit is contained in:
Родитель
c94238ae4f
Коммит
c94a72556d
|
@ -1400,28 +1400,36 @@ nsLayoutUtils::InvalidateForDisplayPortChange(nsIContent* aContent,
|
|||
// rect properties on so we can find the frame later to remove the properties.
|
||||
frame->SchedulePaint();
|
||||
|
||||
if (!gfxPrefs::LayoutRetainDisplayList()) {
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (!retainedBuilder) {
|
||||
return;
|
||||
}
|
||||
|
||||
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
|
||||
|
|
|
@ -760,6 +760,20 @@ ShouldBuildPartial(nsTArray<nsIFrame*>& aModifiedFrames)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
ClearFrameProps(nsTArray<nsIFrame*>& aFrames)
|
||||
{
|
||||
for (nsIFrame* f : aFrames) {
|
||||
if (f->HasOverrideDirtyRegion()) {
|
||||
f->SetHasOverrideDirtyRegion(false);
|
||||
f->DeleteProperty(nsDisplayListBuilder::DisplayListBuildingRect());
|
||||
f->DeleteProperty(nsDisplayListBuilder::DisplayListBuildingDisplayPortRect());
|
||||
}
|
||||
|
||||
f->SetFrameIsModified(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
RetainedDisplayListBuilder::AttemptPartialUpdate(nscolor aBackstop)
|
||||
{
|
||||
|
@ -773,7 +787,10 @@ RetainedDisplayListBuilder::AttemptPartialUpdate(nscolor aBackstop)
|
|||
nsTArray<nsIFrame*> modifiedFrames =
|
||||
GetModifiedFrames(mBuilder.RootReferenceFrame());
|
||||
|
||||
const bool shouldBuildPartial = ShouldBuildPartial(modifiedFrames);
|
||||
// Do not allow partial builds if the retained display list is empty, or if
|
||||
// ShouldBuildPartial heuristic fails.
|
||||
const bool shouldBuildPartial =
|
||||
!mList.IsEmpty() && ShouldBuildPartial(modifiedFrames);
|
||||
|
||||
if (mPreviousCaret != mBuilder.GetCaretFrame()) {
|
||||
if (mPreviousCaret) {
|
||||
|
@ -795,8 +812,9 @@ RetainedDisplayListBuilder::AttemptPartialUpdate(nscolor aBackstop)
|
|||
AnimatedGeometryRoot* modifiedAGR = nullptr;
|
||||
nsTArray<nsIFrame*> framesWithProps;
|
||||
bool merged = false;
|
||||
if (shouldBuildPartial && !mList.IsEmpty() &&
|
||||
ComputeRebuildRegion(modifiedFrames, &modifiedDirty, &modifiedAGR, &framesWithProps)) {
|
||||
if (shouldBuildPartial &&
|
||||
ComputeRebuildRegion(modifiedFrames, &modifiedDirty,
|
||||
&modifiedAGR, &framesWithProps)) {
|
||||
modifiedDirty.IntersectRect(modifiedDirty, mBuilder.RootReferenceFrame()->GetVisualOverflowRectRelativeToSelf());
|
||||
|
||||
PreProcessDisplayList(&mList, modifiedAGR);
|
||||
|
@ -838,21 +856,11 @@ RetainedDisplayListBuilder::AttemptPartialUpdate(nscolor aBackstop)
|
|||
|
||||
mBuilder.LeavePresShell(mBuilder.RootReferenceFrame(), &mList);
|
||||
|
||||
// TODO: Do we mark frames as modified during displaylist building? If
|
||||
// we do this isn't gonna work.
|
||||
for (nsIFrame* f : modifiedFrames) {
|
||||
if (f) {
|
||||
f->SetFrameIsModified(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Override dirty regions should only exist during this function. We set them up during
|
||||
// ComputeRebuildRegion, and clear them here.
|
||||
for (nsIFrame* f: framesWithProps) {
|
||||
f->SetHasOverrideDirtyRegion(false);
|
||||
f->DeleteProperty(nsDisplayListBuilder::DisplayListBuildingRect());
|
||||
f->DeleteProperty(nsDisplayListBuilder::DisplayListBuildingDisplayPortRect());
|
||||
}
|
||||
// We set the override dirty regions during ComputeRebuildRegion or in
|
||||
// nsLayoutUtils::InvalidateForDisplayPortChange. The display port change also
|
||||
// marks the frame modified, so those regions are cleared here as well.
|
||||
ClearFrameProps(modifiedFrames);
|
||||
ClearFrameProps(framesWithProps);
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче