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
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 15 Feb 2018 15:52:37 +1300
changeset 458700 992b8e378397da808cc9c8f0a9b962c8ca469f39
parent 458699 7b7026149e56e8af45061fb7769f83b06c3c7dd8
child 458701 4c62cca5f3ecb2ee93b4d50a4c9427b3fa8f8ccd
push id8808
push userarchaeopteryx@coole-files.de
push dateFri, 02 Mar 2018 22:13:05 +0000
treeherdermozilla-beta@7475508d19db [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1440177
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 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();