зеркало из 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.
|
// rect properties on so we can find the frame later to remove the properties.
|
||||||
frame->SchedulePaint();
|
frame->SchedulePaint();
|
||||||
|
|
||||||
|
if (!gfxPrefs::LayoutRetainDisplayList()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
nsIFrame* displayRoot = nsLayoutUtils::GetDisplayRootFrame(frame);
|
nsIFrame* displayRoot = nsLayoutUtils::GetDisplayRootFrame(frame);
|
||||||
RetainedDisplayListBuilder* retainedBuilder =
|
RetainedDisplayListBuilder* retainedBuilder =
|
||||||
displayRoot->GetProperty(RetainedDisplayListBuilder::Cached());
|
displayRoot->GetProperty(RetainedDisplayListBuilder::Cached());
|
||||||
if (retainedBuilder) {
|
|
||||||
nsRect* rect =
|
if (!retainedBuilder) {
|
||||||
frame->GetProperty(nsDisplayListBuilder::DisplayListBuildingDisplayPortRect());
|
return;
|
||||||
if (!rect) {
|
}
|
||||||
rect = new nsRect();
|
|
||||||
frame->SetProperty(nsDisplayListBuilder::DisplayListBuildingDisplayPortRect(), rect);
|
nsRect* rect =
|
||||||
frame->SetHasOverrideDirtyRegion(true);
|
frame->GetProperty(nsDisplayListBuilder::DisplayListBuildingDisplayPortRect());
|
||||||
}
|
|
||||||
if (aHadDisplayPort) {
|
if (!rect) {
|
||||||
// We only need to build a display list for any new areas added
|
rect = new nsRect();
|
||||||
nsRegion newRegion(aNewDisplayPort);
|
frame->SetProperty(nsDisplayListBuilder::DisplayListBuildingDisplayPortRect(), rect);
|
||||||
newRegion.SubOut(aOldDisplayPort);
|
frame->SetHasOverrideDirtyRegion(true);
|
||||||
rect->UnionRect(*rect, newRegion.GetBounds());
|
}
|
||||||
} else {
|
|
||||||
rect->UnionRect(*rect, aNewDisplayPort);
|
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
|
bool
|
||||||
|
|
|
@ -760,6 +760,20 @@ ShouldBuildPartial(nsTArray<nsIFrame*>& aModifiedFrames)
|
||||||
return true;
|
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
|
bool
|
||||||
RetainedDisplayListBuilder::AttemptPartialUpdate(nscolor aBackstop)
|
RetainedDisplayListBuilder::AttemptPartialUpdate(nscolor aBackstop)
|
||||||
{
|
{
|
||||||
|
@ -773,7 +787,10 @@ RetainedDisplayListBuilder::AttemptPartialUpdate(nscolor aBackstop)
|
||||||
nsTArray<nsIFrame*> modifiedFrames =
|
nsTArray<nsIFrame*> modifiedFrames =
|
||||||
GetModifiedFrames(mBuilder.RootReferenceFrame());
|
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 != mBuilder.GetCaretFrame()) {
|
||||||
if (mPreviousCaret) {
|
if (mPreviousCaret) {
|
||||||
|
@ -795,8 +812,9 @@ RetainedDisplayListBuilder::AttemptPartialUpdate(nscolor aBackstop)
|
||||||
AnimatedGeometryRoot* modifiedAGR = nullptr;
|
AnimatedGeometryRoot* modifiedAGR = nullptr;
|
||||||
nsTArray<nsIFrame*> framesWithProps;
|
nsTArray<nsIFrame*> framesWithProps;
|
||||||
bool merged = false;
|
bool merged = false;
|
||||||
if (shouldBuildPartial && !mList.IsEmpty() &&
|
if (shouldBuildPartial &&
|
||||||
ComputeRebuildRegion(modifiedFrames, &modifiedDirty, &modifiedAGR, &framesWithProps)) {
|
ComputeRebuildRegion(modifiedFrames, &modifiedDirty,
|
||||||
|
&modifiedAGR, &framesWithProps)) {
|
||||||
modifiedDirty.IntersectRect(modifiedDirty, mBuilder.RootReferenceFrame()->GetVisualOverflowRectRelativeToSelf());
|
modifiedDirty.IntersectRect(modifiedDirty, mBuilder.RootReferenceFrame()->GetVisualOverflowRectRelativeToSelf());
|
||||||
|
|
||||||
PreProcessDisplayList(&mList, modifiedAGR);
|
PreProcessDisplayList(&mList, modifiedAGR);
|
||||||
|
@ -838,21 +856,11 @@ RetainedDisplayListBuilder::AttemptPartialUpdate(nscolor aBackstop)
|
||||||
|
|
||||||
mBuilder.LeavePresShell(mBuilder.RootReferenceFrame(), &mList);
|
mBuilder.LeavePresShell(mBuilder.RootReferenceFrame(), &mList);
|
||||||
|
|
||||||
// TODO: Do we mark frames as modified during displaylist building? If
|
// We set the override dirty regions during ComputeRebuildRegion or in
|
||||||
// we do this isn't gonna work.
|
// nsLayoutUtils::InvalidateForDisplayPortChange. The display port change also
|
||||||
for (nsIFrame* f : modifiedFrames) {
|
// marks the frame modified, so those regions are cleared here as well.
|
||||||
if (f) {
|
ClearFrameProps(modifiedFrames);
|
||||||
f->SetFrameIsModified(false);
|
ClearFrameProps(framesWithProps);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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());
|
|
||||||
}
|
|
||||||
|
|
||||||
return merged;
|
return merged;
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче