--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -433,28 +433,26 @@ public:
#endif
, mInvalidateAllLayers(false)
{
MOZ_COUNT_CTOR(LayerManagerData);
}
~LayerManagerData() {
MOZ_COUNT_DTOR(LayerManagerData);
- for (auto iter = mDisplayItems.Iter(); !iter.Done(); iter.Next()) {
- iter.Get()->GetKey()->Disconnect();
+ for (auto& item : mDisplayItems) {
+ item->Disconnect();
}
}
#ifdef DEBUG_DISPLAY_ITEM_DATA
void Dump(const char *aPrefix = "") {
printf_stderr("%sLayerManagerData %p\n", aPrefix, this);
- for (auto iter = mDisplayItems.Iter(); !iter.Done(); iter.Next()) {
- FrameLayerBuilder::DisplayItemData* data = iter.Get()->GetKey();
-
+ for (auto& data : mDisplayItems) {
nsAutoCString prefix;
prefix += aPrefix;
prefix += " ";
const char* layerState;
switch (data->mLayerState) {
case LAYER_NONE:
layerState = "LAYER_NONE"; break;
@@ -502,17 +500,17 @@ public:
/**
* Tracks which frames have layers associated with them.
*/
LayerManager *mLayerManager;
#ifdef DEBUG_DISPLAY_ITEM_DATA
LayerManagerData *mParent;
#endif
- nsTHashtable<nsRefPtrHashKey<DisplayItemData> > mDisplayItems;
+ std::vector<RefPtr<DisplayItemData>> mDisplayItems;
bool mInvalidateAllLayers;
};
/* static */ void
FrameLayerBuilder::DestroyDisplayItemDataFor(nsIFrame* aFrame)
{
RemoveFrameFromLayerManager(aFrame, aFrame->DisplayItemData());
aFrame->DisplayItemData().Clear();
@@ -2141,17 +2139,22 @@ FrameLayerBuilder::RemoveFrameFromLayerM
nsIntRegion rgn = old.ScaleToOutsidePixels(paintedData->mXScale, paintedData->mYScale, paintedData->mAppUnitsPerDevPixel);
rgn.MoveBy(-GetTranslationForPaintedLayer(t));
paintedData->mRegionToInvalidate.Or(paintedData->mRegionToInvalidate, rgn);
paintedData->mRegionToInvalidate.SimplifyOutward(8);
}
}
data->Disconnect();
- data->mParent->mDisplayItems.RemoveEntry(data);
+ auto it = std::find(data->mParent->mDisplayItems.begin(),
+ data->mParent->mDisplayItems.end(),
+ data);
+ MOZ_ASSERT(it != data->mParent->mDisplayItems.end());
+ std::iter_swap(it, data->mParent->mDisplayItems.end() - 1);
+ data->mParent->mDisplayItems.pop_back();
}
arrayCopy.Clear();
sDestroyedFrame = nullptr;
}
void
FrameLayerBuilder::DidBeginRetainedLayerTransaction(LayerManager* aManager)
@@ -2181,38 +2184,52 @@ FrameLayerBuilder::WillEndTransaction()
}
// We need to save the data we'll need to support retaining.
LayerManagerData* data = static_cast<LayerManagerData*>
(mRetainingManager->GetUserData(&gLayerManagerUserData));
NS_ASSERTION(data, "Must have data!");
// Update all the frames that used to have layers.
- for (auto iter = data->mDisplayItems.Iter(); !iter.Done(); iter.Next()) {
- DisplayItemData* data = iter.Get()->GetKey();
- if (!data->mUsed) {
+ auto iter = data->mDisplayItems.begin();
+ while (iter != data->mDisplayItems.end()) {
+ DisplayItemData* did = iter->get();
+ if (!did->mUsed) {
// This item was visible, but isn't anymore.
- PaintedLayer* t = data->mLayer->AsPaintedLayer();
- if (t && data->mGeometry) {
+ PaintedLayer* t = did->mLayer->AsPaintedLayer();
+ if (t && did->mGeometry) {
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
- printf_stderr("Invalidating unused display item (%i) belonging to frame %p from layer %p\n", data->mDisplayItemKey, data->mFrameList[0], t);
+ printf_stderr("Invalidating unused display item (%i) belonging to frame %p from layer %p\n", did->mDisplayItemKey, did->mFrameList[0], t);
}
#endif
InvalidatePostTransformRegion(t,
- data->mGeometry->ComputeInvalidationRegion(),
- data->mClip,
+ did->mGeometry->ComputeInvalidationRegion(),
+ did->mClip,
GetLastPaintOffset(t));
}
- data->ClearAnimationCompositorState();
- data->Disconnect();
- iter.Remove();
+ did->ClearAnimationCompositorState();
+ did->Disconnect();
+
+ // Remove this item. Swapping it with the last element first is
+ // quicker than erasing from the middle.
+ if (iter != data->mDisplayItems.end() - 1) {
+ std::iter_swap(iter, data->mDisplayItems.end() - 1);
+ data->mDisplayItems.pop_back();
+ } else {
+ data->mDisplayItems.pop_back();
+ break;
+ }
+
+ // Don't increment iter because we still need to process the item which was moved.
+
} else {
- ComputeGeometryChangeForItem(data);
+ ComputeGeometryChangeForItem(did);
+ iter++;
}
}
data->mInvalidateAllLayers = false;
}
/* static */ DisplayItemData*
FrameLayerBuilder::GetDisplayItemDataForManager(nsDisplayItem* aItem,
@@ -5113,17 +5130,17 @@ FrameLayerBuilder::StoreDataForFrame(nsD
new (aItem->Frame()->PresContext()) DisplayItemData(lmd, aItem->GetPerFrameKey(), aLayer);
if (!data->HasMergedFrames()) {
aItem->SetDisplayItemData(data);
}
data->BeginUpdate(aLayer, aState, true, aItem);
- lmd->mDisplayItems.PutEntry(data);
+ lmd->mDisplayItems.push_back(data);
return data;
}
void
FrameLayerBuilder::StoreDataForFrame(nsIFrame* aFrame,
uint32_t aDisplayItemKey,
Layer* aLayer,
LayerState aState)
@@ -5137,17 +5154,17 @@ FrameLayerBuilder::StoreDataForFrame(nsI
LayerManagerData* lmd = static_cast<LayerManagerData*>
(mRetainingManager->GetUserData(&gLayerManagerUserData));
RefPtr<DisplayItemData> data =
new (aFrame->PresContext()) DisplayItemData(lmd, aDisplayItemKey, aLayer, aFrame);
data->BeginUpdate(aLayer, aState, true);
- lmd->mDisplayItems.PutEntry(data);
+ lmd->mDisplayItems.push_back(data);
}
AssignedDisplayItem::AssignedDisplayItem(nsDisplayItem* aItem,
LayerState aLayerState,
DisplayItemData* aData,
const nsRect& aContentRect,
DisplayItemEntryType aType,
const bool aHasOpacity)