Bug 1404782 - Do not mutate display list in layers-free mode. r=mattwoodrow draft
authorEthan Lin <ethlin@mozilla.com>
Mon, 02 Oct 2017 11:18:31 +0800
changeset 673316 dd2c809339c6135ad8e602dae74ade87160bbe6a
parent 673315 3043514b2b5807eb436ebad7445db3d2687f08de
child 673336 a5a3e468790cc4fefa0f831ec92f7d0c2915f505
push id82531
push userbmo:ethlin@mozilla.com
push dateMon, 02 Oct 2017 08:53:22 +0000
reviewersmattwoodrow
bugs1404782
milestone58.0a1
Bug 1404782 - Do not mutate display list in layers-free mode. r=mattwoodrow MozReview-Commit-ID: 7usEJupItdi
gfx/layers/wr/WebRenderLayerManager.cpp
--- a/gfx/layers/wr/WebRenderLayerManager.cpp
+++ b/gfx/layers/wr/WebRenderLayerManager.cpp
@@ -214,62 +214,58 @@ WebRenderLayerManager::CreateWebRenderCo
                                                               nsDisplayListBuilder* aDisplayListBuilder,
                                                               const StackingContextHelper& aSc,
                                                               wr::DisplayListBuilder& aBuilder,
                                                               wr::IpcResourceUpdateQueue& aResources)
 {
   bool apzEnabled = AsyncPanZoomEnabled();
   EventRegions eventRegions;
 
-  nsDisplayList savedItems;
-  nsDisplayItem* item;
-  while ((item = aDisplayList->RemoveBottom()) != nullptr) {
+  for (nsDisplayItem* i = aDisplayList->GetBottom(); i; i = i->GetAbove()) {
+    nsDisplayItem* item = i;
     DisplayItemType itemType = item->GetType();
 
     // If the item is a event regions item, but is empty (has no regions in it)
     // then we should just throw it out
     if (itemType == DisplayItemType::TYPE_LAYER_EVENT_REGIONS) {
       nsDisplayLayerEventRegions* eventRegions =
         static_cast<nsDisplayLayerEventRegions*>(item);
       if (eventRegions->IsEmpty()) {
-        item->Destroy(aDisplayListBuilder);
         continue;
       }
     }
 
     // Peek ahead to the next item and try merging with it or swapping with it
     // if necessary.
     AutoTArray<nsDisplayItem*, 1> mergedItems;
     mergedItems.AppendElement(item);
     for (nsDisplayItem* peek = item->GetAbove(); peek; peek = peek->GetAbove()) {
       if (!item->CanMerge(peek)) {
         break;
       }
 
       mergedItems.AppendElement(peek);
 
       // Move the iterator forward since we will merge this item.
-      item = peek;
+      i = peek;
     }
 
     if (mergedItems.Length() > 1) {
       item = aDisplayListBuilder->MergeItems(mergedItems);
       MOZ_ASSERT(item && itemType == item->GetType());
     }
 
-    nsDisplayList* itemSameCoordinateSystemChildren
-      = item->GetSameCoordinateSystemChildren();
+    nsDisplayList* childItems = item->GetSameCoordinateSystemChildren();
     if (item->ShouldFlattenAway(aDisplayListBuilder)) {
-      aDisplayList->AppendToBottom(itemSameCoordinateSystemChildren);
-      item->Destroy(aDisplayListBuilder);
+      MOZ_ASSERT(childItems);
+      CreateWebRenderCommandsFromDisplayList(childItems, aDisplayListBuilder, aSc,
+                                             aBuilder, aResources);
       continue;
     }
 
-    savedItems.AppendToTop(item);
-
     bool forceNewLayerData = false;
     size_t layerCountBeforeRecursing = mLayerScrollData.size();
     if (apzEnabled) {
       // For some types of display items we want to force a new
       // WebRenderLayerScrollData object, to ensure we preserve the APZ-relevant
       // data that is in the display item.
       forceNewLayerData = item->UpdateScrollData(nullptr, nullptr);
 
@@ -356,17 +352,16 @@ WebRenderLayerManager::CreateWebRenderCo
           mAsrStack.empty() ? nullptr : mAsrStack.back();
 
       int32_t descendants = mLayerScrollData.size() - layerCountBeforeRecursing;
 
       mLayerScrollData.emplace_back();
       mLayerScrollData.back().Initialize(mScrollData, item, descendants, stopAtAsr);
     }
   }
-  aDisplayList->AppendToTop(&savedItems);
 
   // If we have any event region info left over we need to flush it before we
   // return. Again, at this point the layer data list must be non-empty, and
   // the most recently created layer data will have been created by an item
   // with matching ASRs.
   if (!eventRegions.IsEmpty()) {
     MOZ_ASSERT(apzEnabled);
     MOZ_ASSERT(!mLayerScrollData.empty());