Bug 1473137 - Convert mOpacityIndices into a stack-based vector with preallocated storage to avoid allocations. r?jnicol draft
authorMatt Woodrow <mwoodrow@mozilla.com>
Tue, 03 Jul 2018 18:58:35 -0400
changeset 813846 4ac82a817c402935031e762848f6617347ded9e0
parent 813581 a0e47ebc4c06e652b919dabee711fdbd6bfd31b5
push id115019
push usermwoodrow@mozilla.com
push dateTue, 03 Jul 2018 22:59:07 +0000
reviewersjnicol
bugs1473137
milestone63.0a1
Bug 1473137 - Convert mOpacityIndices into a stack-based vector with preallocated storage to avoid allocations. r?jnicol MozReview-Commit-ID: Gi5z3YaH7kY
layout/painting/FrameLayerBuilder.cpp
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -574,17 +574,18 @@ public:
    */
   void Accumulate(ContainerState* aState,
                   nsDisplayItem* aItem,
                   const nsIntRect& aVisibleRect,
                   const nsRect& aContentRect,
                   const DisplayItemClip& aClip,
                   LayerState aLayerState,
                   nsDisplayList *aList,
-                  DisplayItemEntryType aType);
+                  DisplayItemEntryType aType,
+                  nsTArray<size_t>& aOpacityIndices);
   AnimatedGeometryRoot* GetAnimatedGeometryRoot() { return mAnimatedGeometryRoot; }
 
   /**
    * A region including the horizontal pan, vertical pan, and no action regions.
    */
   nsRegion CombinedTouchActionRegion();
 
   /**
@@ -763,21 +764,16 @@ public:
    * This is a conservative approximation: it contains the true region.
    */
   nsIntRegion mVisibleAboveRegion;
   /**
    * All the display items that have been assigned to this painted layer.
    * These items get added by Accumulate().
    */
   nsTArray<AssignedDisplayItem> mAssignedDisplayItems;
-  /**
-   * Tracks the active opacity markers by holding the indices to PUSH_OPACITY
-   * items in |mAssignedDisplayItems|.
-   */
-  nsTArray<size_t> mOpacityIndices;
 };
 
 struct NewLayerEntry {
   NewLayerEntry()
     : mAnimatedGeometryRoot(nullptr)
     , mASR(nullptr)
     , mClipChain(nullptr)
     , mScrollMetadataASR(nullptr)
@@ -3346,18 +3342,16 @@ SetBackfaceHiddenForLayer(bool aBackface
   }
 }
 
 template<typename FindOpaqueBackgroundColorCallbackType>
 void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueBackgroundColorCallbackType aFindOpaqueBackgroundColor)
 {
   PaintedLayerData* data = &aData;
 
-  MOZ_ASSERT(data->mOpacityIndices.IsEmpty());
-
   if (!data->mLayer) {
     // No layer was recycled, so we create a new one.
     RefPtr<PaintedLayer> paintedLayer = CreatePaintedLayer(data);
     data->mLayer = paintedLayer;
 
     NS_ASSERTION(FindIndexOfLayerIn(mNewChildLayers, paintedLayer) < 0,
                  "Layer already in list???");
     mNewChildLayers[data->mNewChildLayersIndex].mLayer = paintedLayer.forget();
@@ -3634,28 +3628,29 @@ IsItemAreaInWindowOpaqueRegion(nsDisplay
 void
 PaintedLayerData::Accumulate(ContainerState* aState,
                              nsDisplayItem* aItem,
                              const nsIntRect& aVisibleRect,
                              const nsRect& aContentRect,
                              const DisplayItemClip& aClip,
                              LayerState aLayerState,
                              nsDisplayList* aList,
-                             DisplayItemEntryType aType)
+                             DisplayItemEntryType aType,
+                             nsTArray<size_t>& aOpacityIndices)
 {
   FLB_LOG_PAINTED_LAYER_DECISION(this, "Accumulating dp=%s(%p), f=%p against pld=%p\n", aItem->Name(), aItem, aItem->Frame(), this);
 
-  const bool hasOpacity = mOpacityIndices.Length() > 0;
+  const bool hasOpacity = aOpacityIndices.Length() > 0;
 
   const DisplayItemClip* oldClip = mItemClip;
   mItemClip = &aClip;
 
   if (aType == DisplayItemEntryType::POP_OPACITY) {
-    MOZ_ASSERT(!mOpacityIndices.IsEmpty());
-    mOpacityIndices.RemoveLastElement();
+    MOZ_ASSERT(!aOpacityIndices.IsEmpty());
+    aOpacityIndices.RemoveLastElement();
 
     AssignedDisplayItem item(aItem, aLayerState,
                              nullptr, aContentRect, aType, hasOpacity);
     mAssignedDisplayItems.AppendElement(std::move(item));
     return;
   }
 
   if (aState->mBuilder->NeedToForceTransparentSurfaceForItem(aItem)) {
@@ -3668,17 +3663,17 @@ PaintedLayerData::Accumulate(ContainerSt
     // Note that the transform (if any) on the PaintedLayer is always an integer
     // translation so we don't have to factor that in here.
     aItem->DisableComponentAlpha();
   } else {
     componentAlphaBounds = aItem->GetComponentAlphaBounds(aState->mBuilder);
 
     if (!componentAlphaBounds.IsEmpty()) {
       // This display item needs background copy when pushing opacity group.
-      for (size_t i : mOpacityIndices) {
+      for (size_t i : aOpacityIndices) {
         AssignedDisplayItem& item = mAssignedDisplayItems[i];
         MOZ_ASSERT(item.mType == DisplayItemEntryType::PUSH_OPACITY ||
                    item.mType == DisplayItemEntryType::PUSH_OPACITY_WITH_BG);
         item.mType = DisplayItemEntryType::PUSH_OPACITY_WITH_BG;
       }
     }
   }
 
@@ -3691,17 +3686,17 @@ PaintedLayerData::Accumulate(ContainerSt
     aState->mLayerBuilder->GetOldLayerForFrame(aItem->Frame(),
                                                aItem->GetPerFrameKey(),
                                                currentData);
   AssignedDisplayItem item(aItem, aLayerState,
                            oldData, aContentRect, aType, hasOpacity);
   mAssignedDisplayItems.AppendElement(std::move(item));
 
   if (aType == DisplayItemEntryType::PUSH_OPACITY) {
-    mOpacityIndices.AppendElement(mAssignedDisplayItems.Length() - 1);
+    aOpacityIndices.AppendElement(mAssignedDisplayItems.Length() - 1);
   }
 
   if (aItem->MustPaintOnContentSide()) {
      mShouldPaintOnContentSide = true;
   }
 
   if (!mIsSolidColorInVisibleRegion && mOpaqueRegion.Contains(aVisibleRect) &&
       mVisibleRegion.Contains(aVisibleRect) && !mImage) {
@@ -4283,16 +4278,17 @@ ContainerState::ProcessDisplayItems(nsDi
   }
 
   AnimatedGeometryRoot* lastAnimatedGeometryRoot = nullptr;
   nsPoint lastTopLeft;
 
   // Tracks the PaintedLayerData that the item will be accumulated in, if it is
   // non-null. Currently only used with PUSH_OPACITY and POP_OPACITY markers.
   PaintedLayerData* selectedPLD = nullptr;
+  AutoTArray<size_t, 2> opacityIndices;
 
   FLBDisplayItemIterator iter(mBuilder, aList, this);
   while (iter.HasNext()) {
     DisplayItemEntry e = iter.GetNextEntry();
     nsDisplayItem* i = e.mItem;
     DisplayItemEntryType marker = e.mType;
 
 
@@ -4836,17 +4832,17 @@ ContainerState::ProcessDisplayItems(nsDi
       MOZ_ASSERT(paintedLayerData);
 
       if (itemType == DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO) {
         nsDisplayCompositorHitTestInfo* hitTestInfo =
           static_cast<nsDisplayCompositorHitTestInfo*>(item);
         paintedLayerData->AccumulateHitTestInfo(this, hitTestInfo);
       } else {
         paintedLayerData->Accumulate(this, item, itemVisibleRect, itemContent, itemClip,
-                                     layerState, aList, marker);
+                                     layerState, aList, marker, opacityIndices);
 
         if (!paintedLayerData->mLayer) {
           // Try to recycle the old layer of this display item.
           RefPtr<PaintedLayer> layer =
             AttemptToRecyclePaintedLayer(animatedGeometryRoot, item,
                                          topLeft, referenceFrame);
           if (layer) {
             paintedLayerData->mLayer = layer;
@@ -4863,17 +4859,17 @@ ContainerState::ProcessDisplayItems(nsDi
 
       if (marker == DisplayItemEntryType::PUSH_OPACITY) {
         selectedPLD = paintedLayerData;
       }
 
       if (marker == DisplayItemEntryType::POP_OPACITY ) {
         MOZ_ASSERT(selectedPLD);
 
-        if (selectedPLD->mOpacityIndices.IsEmpty()) {
+        if (opacityIndices.IsEmpty()) {
           selectedPLD = nullptr;
         }
       }
     }
 
     nsDisplayList* childItems = item->GetSameCoordinateSystemChildren();
     if (childItems && childItems->NeedsTransparentSurface()) {
       aList->SetNeedsTransparentSurface();