Bug 1555819 - Remove invalidated display items during PreProcessDisplayLists, since we might not merge their display list. r=miko

Differential Revision: https://phabricator.services.mozilla.com/D33881

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Matt Woodrow 2019-06-07 01:55:57 +00:00
parent d436383750
commit bc3e85dc75
4 changed files with 42 additions and 24 deletions

View File

@ -114,6 +114,23 @@ static AnimatedGeometryRoot* SelectAGRForFrame(
return data && data->mModifiedAGR ? data->mModifiedAGR.get() : nullptr;
}
bool AnyContentAncestorModified(nsIFrame* aFrame, nsIFrame* aStopAtFrame) {
nsIFrame* f = aFrame;
while (f) {
if (f->IsFrameModified()) {
return true;
}
if (aStopAtFrame && f == aStopAtFrame) {
break;
}
f = nsLayoutUtils::GetDisplayListParent(f);
}
return false;
}
// Removes any display items that belonged to a frame that was deleted,
// and mark frames that belong to a different AGR so that get their
// items built again.
@ -122,8 +139,8 @@ static AnimatedGeometryRoot* SelectAGRForFrame(
// jump into those immediately rather than walking the entire thing.
bool RetainedDisplayListBuilder::PreProcessDisplayList(
RetainedDisplayList* aList, AnimatedGeometryRoot* aAGR,
PartialUpdateResult& aUpdated, uint32_t aCallerKey, uint32_t aNestingDepth,
bool aKeepLinked) {
PartialUpdateResult& aUpdated, nsIFrame* aOuterFrame, uint32_t aCallerKey,
uint32_t aNestingDepth, bool aKeepLinked) {
// The DAG merging algorithm does not have strong mechanisms in place to keep
// the complexity of the resulting DAG under control. In some cases we can
// build up edges very quickly. Detect those cases and force a full display
@ -179,7 +196,8 @@ bool RetainedDisplayListBuilder::PreProcessDisplayList(
}
}
if (!item->CanBeReused() || item->HasDeletedFrame()) {
if (!item->CanBeReused() || item->HasDeletedFrame() ||
AnyContentAncestorModified(item->FrameForInvalidation(), aOuterFrame)) {
if (initializeOldItems) {
aList->mOldItems.AppendElement(OldItemInfo(nullptr));
} else {
@ -231,9 +249,10 @@ bool RetainedDisplayListBuilder::PreProcessDisplayList(
keepLinked = true;
}
if (!PreProcessDisplayList(
item->GetChildren(), SelectAGRForFrame(f, aAGR), aUpdated,
item->GetPerFrameKey(), aNestingDepth + 1, keepLinked)) {
if (!PreProcessDisplayList(item->GetChildren(),
SelectAGRForFrame(f, aAGR), aUpdated,
item->Frame(), item->GetPerFrameKey(),
aNestingDepth + 1, keepLinked)) {
MOZ_RELEASE_ASSERT(
!aKeepLinked,
"Can't early return since we need to move the out list back");
@ -295,23 +314,6 @@ void RetainedDisplayListBuilder::IncrementSubDocPresShellPaintCount(
mBuilder.IncrementPresShellPaintCount(presShell);
}
bool AnyContentAncestorModified(nsIFrame* aFrame, nsIFrame* aStopAtFrame) {
nsIFrame* f = aFrame;
while (f) {
if (f->IsFrameModified()) {
return true;
}
if (aStopAtFrame && f == aStopAtFrame) {
break;
}
f = nsLayoutUtils::GetDisplayListParent(f);
}
return false;
}
static Maybe<const ActiveScrolledRoot*> SelectContainerASR(
const DisplayItemClipChain* aClipChain, const ActiveScrolledRoot* aItemASR,
Maybe<const ActiveScrolledRoot*>& aContainerASR) {
@ -620,10 +622,12 @@ class MergeState {
return false;
}
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
bool HasModifiedFrame(nsDisplayItem* aItem) {
nsIFrame* stopFrame = mOuterItem ? mOuterItem->Frame() : nullptr;
return AnyContentAncestorModified(aItem->FrameForInvalidation(), stopFrame);
}
#endif
void UpdateContainerASR(nsDisplayItem* aItem) {
mContainerASR = SelectContainerASR(
@ -661,7 +665,7 @@ class MergeState {
void ProcessOldNode(OldListIndex aNode,
nsTArray<MergedListIndex>&& aDirectPredecessors) {
nsDisplayItem* item = mOldItems[aNode.val].mItem;
if (mOldItems[aNode.val].IsChanged() || HasModifiedFrame(item)) {
if (mOldItems[aNode.val].IsChanged()) {
if (item && item->IsGlassItem() &&
item == mBuilder->Builder()->GetGlassDisplayItem()) {
mBuilder->Builder()->ClearGlassDisplayItem();

View File

@ -215,6 +215,7 @@ struct RetainedDisplayListBuilder {
bool PreProcessDisplayList(RetainedDisplayList* aList,
AnimatedGeometryRoot* aAGR,
PartialUpdateResult& aUpdated,
nsIFrame* aOuterFrame = nullptr,
uint32_t aCallerKey = 0,
uint32_t aNestingDepth = 0,
bool aKeepLinked = false);

View File

@ -0,0 +1,12 @@
<style>
body {
width: 1px;
height: 5vmax;
-webkit-filter: brightness(1);
}
* {
grid-template-areas: '';
columns: 1px;
}
</style>
<keygen autofocus="">aaaa

View File

@ -20,4 +20,5 @@ load 1514544-1.html
load 1547420-1.html
load 1549909.html
asserts(6) load 1551389-1.html # bug 847368
asserts(0-2) load 1555819-1.html