Bug 1404782 - Do not mutate display list in layers-free mode. r=mattwoodrow
MozReview-Commit-ID: 7usEJupItdi
--- 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());