Bug 1440177 - Part 4: Avoid expensive hashtable lookups in PaintedLayerDataTree when we're in an inactive layer and want all items in the same layer. r?mstange draft
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 15 Feb 2018 15:52:37 +1300
changeset 762223 96a378972755cf43621e9a09e2f92eeeb20ee92e
parent 762222 a136e473da15901a9683d5ccf145ade9dc987eba
child 762224 5190523dd6cf20ccae2d6621204e23e8d23c3d4c
push id101106
push usermwoodrow@mozilla.com
push dateThu, 01 Mar 2018 22:19:48 +0000
reviewersmstange
bugs1440177
milestone60.0a1
Bug 1440177 - Part 4: Avoid expensive hashtable lookups in PaintedLayerDataTree when we're in an inactive layer and want all items in the same layer. r?mstange MozReview-Commit-ID: AWsXw2ZrL9Q
layout/painting/FrameLayerBuilder.cpp
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -921,24 +921,27 @@ class ContainerState;
  * the tree.
  */
 class PaintedLayerDataTree {
 public:
   PaintedLayerDataTree(ContainerState& aContainerState,
                        nscolor& aBackgroundColor)
     : mContainerState(aContainerState)
     , mContainerUniformBackgroundColor(aBackgroundColor)
+    , mForInactiveLayer(false)
   {}
 
   ~PaintedLayerDataTree()
   {
     MOZ_ASSERT(!mRoot);
     MOZ_ASSERT(mNodes.Count() == 0);
   }
 
+  void InitializeForInactiveLayer(AnimatedGeometryRoot* aAnimatedGeometryRoot);
+
   /**
    * Notify our contents that some non-PaintedLayer content has been added.
    * *aRect needs to be a rectangle that doesn't move with respect to
    * aAnimatedGeometryRoot and that contains the added item.
    * If aRect is null, the extents will be considered infinite.
    * If aOutUniformBackgroundColor is non-null, it will be set to an opaque
    * color that can be pulled into the background of the added content, or
    * transparent if that is not possible.
@@ -1016,31 +1019,33 @@ protected:
    * in the search up from aAnimatedGeometryRoot; it will be a child animated
    * geometry root of the result, if neither are null.
    */
   PaintedLayerDataNode*
     FindNodeForAncestorAnimatedGeometryRoot(AnimatedGeometryRoot* aAnimatedGeometryRoot,
                                             AnimatedGeometryRoot** aOutAncestorChild);
 
   ContainerState& mContainerState;
-  UniquePtr<PaintedLayerDataNode> mRoot;
+  Maybe<PaintedLayerDataNode> mRoot;
 
   /**
    * The uniform opaque color from behind this container layer, or
    * NS_RGBA(0,0,0,0) if the background behind this container layer is not
    * uniform and opaque. This color can be pulled into PaintedLayers that are
    * directly above the background.
    */
   nscolor mContainerUniformBackgroundColor;
 
   /**
    * A hash map for quick access the node belonging to a particular animated
    * geometry root.
    */
   nsDataHashtable<nsPtrHashKey<AnimatedGeometryRoot>, PaintedLayerDataNode*> mNodes;
+
+  bool mForInactiveLayer;
 };
 
 /**
  * This is a helper object used to build up the layer children for
  * a ContainerLayer.
  */
 class ContainerState {
 public:
@@ -2915,45 +2920,58 @@ PaintedLayerDataNode::PopAllPaintedLayer
     PaintedLayerData& data = mPaintedLayerDataStack[index];
     mTree.ContState().FinishPaintedLayerData(data, [this, &data, index]() {
       return this->FindOpaqueBackgroundColor(data.mVisibleRegion, index);
     });
   }
   mPaintedLayerDataStack.Clear();
 }
 
+void
+PaintedLayerDataTree::InitializeForInactiveLayer(AnimatedGeometryRoot* aAnimatedGeometryRoot)
+{
+  mForInactiveLayer = true;
+  mRoot.emplace(*this, nullptr, aAnimatedGeometryRoot);
+
+}
+
 nsDisplayListBuilder*
 PaintedLayerDataTree::Builder() const
 {
   return mContainerState.Builder();
 }
 
 void
 PaintedLayerDataTree::Finish()
 {
   if (mRoot) {
     mRoot->Finish(false);
   }
   MOZ_ASSERT(mNodes.Count() == 0);
-  mRoot = nullptr;
+  mRoot.reset();
 }
 
 void
 PaintedLayerDataTree::NodeWasFinished(AnimatedGeometryRoot* aAnimatedGeometryRoot)
 {
   mNodes.Remove(aAnimatedGeometryRoot);
 }
 
 void
 PaintedLayerDataTree::AddingOwnLayer(AnimatedGeometryRoot* aAnimatedGeometryRoot,
                                      const nsIntRect* aRect,
                                      nscolor* aOutUniformBackgroundColor)
 {
-  FinishPotentiallyIntersectingNodes(aAnimatedGeometryRoot, aRect);
-  PaintedLayerDataNode* node = EnsureNodeFor(aAnimatedGeometryRoot);
+  PaintedLayerDataNode* node = nullptr;
+  if (mForInactiveLayer) {
+    node = mRoot.ptr();
+  } else {
+    FinishPotentiallyIntersectingNodes(aAnimatedGeometryRoot, aRect);
+    node = EnsureNodeFor(aAnimatedGeometryRoot);
+  }
   if (aRect) {
     if (aOutUniformBackgroundColor) {
       *aOutUniformBackgroundColor = node->FindOpaqueBackgroundColor(*aRect);
     }
     node->AddToVisibleAboveRegion(*aRect);
   } else {
     if (aOutUniformBackgroundColor) {
       *aOutUniformBackgroundColor = node->FindOpaqueBackgroundColorCoveringEverything();
@@ -2967,18 +2985,23 @@ PaintedLayerData*
 PaintedLayerDataTree::FindPaintedLayerFor(AnimatedGeometryRoot* aAnimatedGeometryRoot,
                                           const ActiveScrolledRoot* aASR,
                                           const DisplayItemClipChain* aClipChain,
                                           const nsIntRect& aVisibleRect,
                                           const bool aBackfaceHidden,
                                           NewPaintedLayerCallbackType aNewPaintedLayerCallback)
 {
   const nsIntRect* bounds = &aVisibleRect;
-  FinishPotentiallyIntersectingNodes(aAnimatedGeometryRoot, bounds);
-  PaintedLayerDataNode* node = EnsureNodeFor(aAnimatedGeometryRoot);
+  PaintedLayerDataNode* node = nullptr;
+  if (mForInactiveLayer) {
+    node = mRoot.ptr();
+  } else {
+    FinishPotentiallyIntersectingNodes(aAnimatedGeometryRoot, bounds);
+    node = EnsureNodeFor(aAnimatedGeometryRoot);
+  }
 
   PaintedLayerData* data =
     node->FindPaintedLayerFor(aVisibleRect, aBackfaceHidden, aASR, aClipChain,
                               aNewPaintedLayerCallback);
   return data;
 }
 
 void
@@ -3037,32 +3060,35 @@ PaintedLayerDataTree::EnsureNodeFor(Anim
   if (node) {
     return node;
   }
 
   AnimatedGeometryRoot* parentAnimatedGeometryRoot = aAnimatedGeometryRoot->mParentAGR;
   if (!parentAnimatedGeometryRoot) {
     MOZ_ASSERT(!mRoot);
     MOZ_ASSERT(*aAnimatedGeometryRoot == Builder()->RootReferenceFrame());
-    mRoot = MakeUnique<PaintedLayerDataNode>(*this, nullptr, aAnimatedGeometryRoot);
-    node = mRoot.get();
+    mRoot.emplace(*this, nullptr, aAnimatedGeometryRoot);
+    node = mRoot.ptr();
   } else {
     PaintedLayerDataNode* parentNode = EnsureNodeFor(parentAnimatedGeometryRoot);
     MOZ_ASSERT(parentNode);
     node = parentNode->AddChildNodeFor(aAnimatedGeometryRoot);
   }
   MOZ_ASSERT(node);
   mNodes.Put(aAnimatedGeometryRoot, node);
   return node;
 }
 
 bool
 PaintedLayerDataTree::IsClippedWithRespectToParentAnimatedGeometryRoot(AnimatedGeometryRoot* aAnimatedGeometryRoot,
                                                                        nsIntRect* aOutClip)
 {
+  if (mForInactiveLayer) {
+    return false;
+  }
   nsIScrollableFrame* scrollableFrame = nsLayoutUtils::GetScrollableFrameFor(*aAnimatedGeometryRoot);
   if (!scrollableFrame) {
     return false;
   }
   nsIFrame* scrollFrame = do_QueryFrame(scrollableFrame);
   nsRect scrollPort = scrollableFrame->GetScrollPortRect() + Builder()->ToReferenceFrame(scrollFrame);
   *aOutClip = mContainerState.ScaleToNearestPixels(scrollPort);
   return true;
@@ -4115,16 +4141,20 @@ ContainerState::ProcessDisplayItems(nsDi
   int32_t maxLayers = gfxPrefs::MaxActiveLayers();
   int layerCount = 0;
 
 #ifdef DEBUG
   bool hadLayerEventRegions = false;
   bool hadCompositorHitTestInfo = false;
 #endif
 
+  if (!mManager->IsWidgetLayerManager()) {
+    mPaintedLayerDataTree.InitializeForInactiveLayer(mContainerAnimatedGeometryRoot);
+  }
+
   AnimatedGeometryRoot* lastAnimatedGeometryRoot = nullptr;
   nsPoint lastTopLeft;
   FlattenedDisplayItemIterator iter(mBuilder, aList);
   while (nsDisplayItem* i = iter.GetNext()) {
     nsDisplayItem* item = i;
     MOZ_ASSERT(item);
 
     DisplayItemType itemType = item->GetType();