Bug 1526972 - P4: Limit AnyContentAncestorModified frame walk to frame of outer item. r=miko
☠☠ backed out by 9f0f38c38ccc ☠ ☠
authorDan Glastonbury <dan.glastonbury@gmail.com>
Mon, 15 Apr 2019 00:23:13 +0000
changeset 469450 8543b9d465212a64ee52a84f1da4760cfda702fa
parent 469449 ddd57e4372286632c4759d84d86cba27b30fc3a2
child 469451 2fb940b13971110b8ef299730a03f37f65ae372a
push id112792
push userncsoregi@mozilla.com
push dateMon, 15 Apr 2019 09:49:11 +0000
treeherdermozilla-inbound@a57f27d3ccd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmiko
bugs1526972
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1526972 - P4: Limit AnyContentAncestorModified frame walk to frame of outer item. r=miko Don't walk frame tree all the way to the root. Depends on D24461 Differential Revision: https://phabricator.services.mozilla.com/D26137
layout/painting/RetainedDisplayListBuilder.cpp
--- a/layout/painting/RetainedDisplayListBuilder.cpp
+++ b/layout/painting/RetainedDisplayListBuilder.cpp
@@ -301,24 +301,24 @@ bool OldItemInfo::IsChanged() {
  * MergeState handles combining a new list of display items into an existing
  * DAG and computes the new DAG in a single pass.
  * Each time we add a new item, we resolve all dependencies for it, so that the
  * resulting list and DAG are built in topological ordering.
  */
 class MergeState {
  public:
   MergeState(RetainedDisplayListBuilder* aBuilder,
-             RetainedDisplayList& aOldList, uint32_t aOuterKey)
+             RetainedDisplayList& aOldList, nsDisplayItem* aOuterItem)
       : mBuilder(aBuilder),
         mOldList(&aOldList),
         mOldItems(std::move(aOldList.mOldItems)),
         mOldDAG(
             std::move(*reinterpret_cast<DirectedAcyclicGraph<OldListUnits>*>(
                 &aOldList.mDAG))),
-        mOuterKey(aOuterKey),
+        mOuterItem(aOuterItem),
         mResultIsModified(false) {
     mMergedDAG.EnsureCapacityFor(mOldDAG);
     MOZ_RELEASE_ASSERT(mOldItems.Length() == mOldDAG.Length());
   }
 
   Maybe<MergedListIndex> ProcessItemFromNewList(
       nsDisplayItem* aNewItem, const Maybe<MergedListIndex>& aPreviousItem) {
     OldListIndex oldIndex;
@@ -457,29 +457,31 @@ class MergeState {
     return result;
   }
 
   bool HasMatchingItemInOldList(nsDisplayItem* aItem, OldListIndex* aOutIndex) {
     nsIFrame::DisplayItemArray* items =
         aItem->Frame()->GetProperty(nsIFrame::DisplayItems());
     // Look for an item that matches aItem's frame and per-frame-key, but isn't
     // the same item.
+    uint32_t outerKey = mOuterItem ? mOuterItem->GetPerFrameKey() : 0;
     for (nsDisplayItem* i : *items) {
       if (i != aItem && i->Frame() == aItem->Frame() &&
           i->GetPerFrameKey() == aItem->GetPerFrameKey()) {
-        if (i->GetOldListIndex(mOldList, mOuterKey, aOutIndex)) {
+        if (i->GetOldListIndex(mOldList, outerKey, aOutIndex)) {
           return true;
         }
       }
     }
     return false;
   }
 
   bool HasModifiedFrame(nsDisplayItem* aItem) {
-    return AnyContentAncestorModified(aItem->FrameForInvalidation());
+    nsIFrame* stopFrame = mOuterItem ? mOuterItem->Frame() : nullptr;
+    return AnyContentAncestorModified(aItem->FrameForInvalidation(), stopFrame);
   }
 
   void UpdateContainerASR(nsDisplayItem* aItem) {
     mContainerASR = SelectContainerASR(
         aItem->GetClipChain(), aItem->GetActiveScrolledRoot(), mContainerASR);
   }
 
   MergedListIndex AddNewNode(
@@ -612,17 +614,17 @@ class MergeState {
   Maybe<const ActiveScrolledRoot*> mContainerASR;
   nsTArray<OldItemInfo> mOldItems;
   DirectedAcyclicGraph<OldListUnits> mOldDAG;
   // Unfortunately we can't use strong typing for the hashtables
   // since they internally encode the type with the mOps pointer,
   // and assert when we try swap the contents
   nsDisplayList mMergedItems;
   DirectedAcyclicGraph<MergedListUnits> mMergedDAG;
-  uint32_t mOuterKey;
+  nsDisplayItem* mOuterItem;
   bool mResultIsModified;
 };
 
 /**
  * Takes two display lists and merges them into an output list.
  *
  * Display lists wthout an explicit DAG are interpreted as linear DAGs (with a
  * maximum of one direct predecessor and one direct successor per node). We add
@@ -634,18 +636,17 @@ class MergeState {
  */
 bool RetainedDisplayListBuilder::MergeDisplayLists(
     nsDisplayList* aNewList, RetainedDisplayList* aOldList,
     RetainedDisplayList* aOutList,
     mozilla::Maybe<const mozilla::ActiveScrolledRoot*>& aOutContainerASR,
     nsDisplayItem* aOuterItem) {
   AUTO_PROFILER_LABEL_CATEGORY_PAIR(GRAPHICS_DisplayListMerging);
 
-  MergeState merge(this, *aOldList,
-                   aOuterItem ? aOuterItem->GetPerFrameKey() : 0);
+  MergeState merge(this, *aOldList, aOuterItem);
 
   Maybe<MergedListIndex> previousItemIndex;
   while (nsDisplayItem* item = aNewList->RemoveBottom()) {
     previousItemIndex = merge.ProcessItemFromNewList(item, previousItemIndex);
   }
 
   *aOutList = merge.Finalize();
   aOutContainerASR = merge.mContainerASR;