Bug 1440966 - Store optimized Layer in DisplayItemData as part of AddPaintedLayerFor. r=jnicol
authorMatt Woodrow <mwoodrow@mozilla.com>
Wed, 07 Mar 2018 15:42:43 +1300
changeset 462179 fe859b4ec63cc8737ad26a1ca2bc2e7bfaa6dcdc
parent 462178 2c63728fdf4b4c5d522a382a47df2aed6bff03c4
child 462180 95d553c23d52e49433096f02de048556b78db577
push id1683
push usersfraser@mozilla.com
push dateThu, 26 Apr 2018 16:43:40 +0000
treeherdermozilla-release@5af6cb21869d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjnicol
bugs1440966
milestone60.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 1440966 - Store optimized Layer in DisplayItemData as part of AddPaintedLayerFor. r=jnicol
layout/painting/FrameLayerBuilder.cpp
layout/painting/FrameLayerBuilder.h
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -2007,29 +2007,16 @@ FrameLayerBuilder::DidBeginRetainedLayer
     mInvalidateAllLayers = data->mInvalidateAllLayers;
   } else {
     data = new LayerManagerData(aManager);
     aManager->SetUserData(&gLayerManagerUserData, data);
   }
 }
 
 void
-FrameLayerBuilder::StoreOptimizedLayerForFrame(nsDisplayItem* aItem, Layer* aLayer)
-{
-  if (!mRetainingManager) {
-    return;
-  }
-
-  DisplayItemData* data = GetDisplayItemDataForManager(aItem, aLayer->Manager());
-  NS_ASSERTION(data, "Must have already stored data for this item!");
-  data->mOptLayer = aLayer;
-  data->mItem = nullptr;
-}
-
-void
 FrameLayerBuilder::DidEndTransaction()
 {
   GetMaskLayerImageCache()->Sweep();
 }
 
 void
 FrameLayerBuilder::WillEndTransaction()
 {
@@ -3187,26 +3174,16 @@ void ContainerState::FinishPaintedLayerD
     RefPtr<PaintedLayer> paintedLayer = CreatePaintedLayer(data);
     data->mLayer = paintedLayer;
 
     NS_ASSERTION(FindIndexOfLayerIn(mNewChildLayers, paintedLayer) < 0,
                  "Layer already in list???");
     mNewChildLayers[data->mNewChildLayersIndex].mLayer = paintedLayer.forget();
   }
 
-  for (auto& item : data->mAssignedDisplayItems) {
-    MOZ_ASSERT(item.mItem->GetType() != DisplayItemType::TYPE_LAYER_EVENT_REGIONS);
-    MOZ_ASSERT(item.mItem->GetType() != DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO);
-
-    InvalidateForLayerChange(item.mItem, data->mLayer, item.mDisplayItemData);
-    mLayerBuilder->AddPaintedDisplayItem(data, item, *this,
-                                         data->mAnimatedGeometryRootOffset);
-    item.mDisplayItemData = nullptr;
-  }
-
   PaintedDisplayItemLayerUserData* userData = GetPaintedDisplayItemLayerUserData(data->mLayer);
   NS_ASSERTION(userData, "where did our user data go?");
   userData->mLastItemCount = data->mAssignedDisplayItems.Length();
 
   NewLayerEntry* newLayerEntry = &mNewChildLayers[data->mNewChildLayersIndex];
 
   RefPtr<Layer> layer;
   bool canOptimizeToImageLayer = data->CanOptimizeToImageLayer(mBuilder);
@@ -3241,30 +3218,35 @@ void ContainerState::FinishPaintedLayerD
 
       // Hide the PaintedLayer. We leave it in the layer tree so that we
       // can find and recycle it later.
       ParentLayerIntRect emptyRect;
       data->mLayer->SetClipRect(Some(emptyRect));
       data->mLayer->SetVisibleRegion(LayerIntRegion());
       data->mLayer->InvalidateWholeLayer();
       data->mLayer->SetEventRegions(EventRegions());
-
-      for (auto& item : data->mAssignedDisplayItems) {
-        mLayerBuilder->StoreOptimizedLayerForFrame(item.mItem, layer);
-      }
     }
   }
 
   if (!layer) {
     // We couldn't optimize to an image layer or a color layer above.
     layer = data->mLayer;
     layer->SetClipRect(Nothing());
     FLB_LOG_PAINTED_LAYER_DECISION(data, "  Selected painted layer=%p\n", layer.get());
   }
 
+  for (auto& item : data->mAssignedDisplayItems) {
+    MOZ_ASSERT(item.mItem->GetType() != DisplayItemType::TYPE_LAYER_EVENT_REGIONS);
+    MOZ_ASSERT(item.mItem->GetType() != DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO);
+
+    InvalidateForLayerChange(item.mItem, data->mLayer, item.mDisplayItemData);
+    mLayerBuilder->AddPaintedDisplayItem(data, item, *this, layer);
+    item.mDisplayItemData = nullptr;
+  }
+
   if (mLayerBuilder->IsBuildingRetainedLayers()) {
     newLayerEntry->mVisibleRegion = data->mVisibleRegion;
     newLayerEntry->mOpaqueRegion = data->mOpaqueRegion;
     newLayerEntry->mHideAllLayersBelow = data->mHideAllLayersBelow;
     newLayerEntry->mOpaqueForAnimatedGeometryRootParent = data->mOpaqueForAnimatedGeometryRootParent;
   } else {
     SetOuterVisibleRegionForLayer(layer, data->mVisibleRegion);
   }
@@ -4779,33 +4761,33 @@ FrameLayerBuilder::ComputeGeometryChange
 
   aData->EndUpdate(geometry);
 }
 
 void
 FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
                                          AssignedDisplayItem& aItem,
                                          ContainerState& aContainerState,
-                                         const nsPoint& aTopLeft)
+                                         Layer* aLayer)
 {
   PaintedLayer* layer = aLayerData->mLayer;
   PaintedDisplayItemLayerUserData* paintedData =
     static_cast<PaintedDisplayItemLayerUserData*>
       (layer->GetUserData(&gPaintedDisplayItemLayerUserData));
   RefPtr<BasicLayerManager> tempManager;
   nsIntRect intClip;
   bool hasClip = false;
   if (aItem.mLayerState != LAYER_NONE) {
     if (aItem.mDisplayItemData) {
       tempManager = aItem.mDisplayItemData->mInactiveManager;
 
       // We need to grab these before updating the DisplayItemData because it will overwrite them.
       nsRegion clip;
       if (aItem.mClip.ComputeRegionInClips(&aItem.mDisplayItemData->GetClip(),
-                                     aTopLeft - paintedData->mLastAnimatedGeometryRootOrigin,
+                                     aLayerData->mAnimatedGeometryRootOffset - paintedData->mLastAnimatedGeometryRootOrigin,
                                      &clip)) {
         intClip = clip.GetBounds().ScaleToOutsidePixels(paintedData->mXScale,
                                                         paintedData->mYScale,
                                                         paintedData->mAppUnitsPerDevPixel);
       }
     }
     if (!tempManager) {
       tempManager = new BasicLayerManager(BasicLayerManager::BLM_INACTIVE);
@@ -4817,16 +4799,22 @@ FrameLayerBuilder::AddPaintedDisplayItem
     if (data) {
       if (!data->mUsed) {
         data->BeginUpdate(layer, aItem.mLayerState, aItem.mItem, aItem.mReused, aItem.mMerged);
       }
     } else {
       data = StoreDataForFrame(aItem.mItem, layer, aItem.mLayerState, nullptr);
     }
     data->mInactiveManager = tempManager;
+    // We optimized this PaintedLayer into a ColorLayer/ImageLayer. Store the optimized
+    // layer here.
+    if (aLayer != layer) {
+      data->mOptLayer = aLayer;
+      data->mItem = nullptr;
+    }
   }
 
   if (tempManager) {
     FLB_LOG_PAINTED_LAYER_DECISION(aLayerData, "Creating nested FLB for item %p\n", aItem.mItem);
     FrameLayerBuilder* layerBuilder = new FrameLayerBuilder();
     layerBuilder->Init(mDisplayListBuilder, tempManager, aLayerData, true,
                        &aItem.mClip);
 
--- a/layout/painting/FrameLayerBuilder.h
+++ b/layout/painting/FrameLayerBuilder.h
@@ -505,20 +505,20 @@ public:
 
   /**
    * Record aItem as a display item that is rendered by the PaintedLayer
    * aLayer, with aClipRect, where aContainerLayerFrame is the frame
    * for the container layer this ThebesItem belongs to.
    * aItem must have an underlying frame.
    * @param aTopLeft offset from active scrolled root to reference frame
    */
-  void AddPaintedDisplayItem(PaintedLayerData* aLayer,
+  void AddPaintedDisplayItem(PaintedLayerData* aLayerData,
                              AssignedDisplayItem& aAssignedDisplayItem,
                              ContainerState& aContainerState,
-                             const nsPoint& aTopLeft);
+                             Layer* aLayer);
 
   /**
    * Calls GetOldLayerForFrame on the underlying frame of the display item,
    * and each subsequent merged frame if no layer is found for the underlying
    * frame.
    */
   Layer* GetOldLayerFor(nsDisplayItem* aItem,
                         nsDisplayItemGeometry** aOldGeometry = nullptr,
@@ -585,24 +585,16 @@ public:
    * Return the resolution at which we expect to render aFrame's contents,
    * assuming they are being painted to retained layers. This takes into account
    * the resolution the contents of the ContainerLayer containing aFrame are
    * being rendered at, as well as any currently-inactive transforms between
    * aFrame and that container layer.
    */
   static gfxSize GetPaintedLayerScaleForFrame(nsIFrame* aFrame);
 
-  /**
-   * Stores a Layer as the dedicated layer in the DisplayItemData for a given frame/key pair.
-   *
-   * Used when we optimize a PaintedLayer into an ImageLayer and want to retroactively update the
-   * DisplayItemData so we can retrieve the layer from within layout.
-   */
-  void StoreOptimizedLayerForFrame(nsDisplayItem* aItem, Layer* aLayer);
-
   static void RemoveFrameFromLayerManager(const nsIFrame* aFrame,
                                           SmallPointerArray<DisplayItemData>& aArray);
 
   /**
    * Given a frame and a display item key that uniquely identifies a
    * display item for the frame, find the layer that was last used to
    * render that display item. Returns null if there is no such layer.
    * This could be a dedicated layer for the display item, or a PaintedLayer