Bug 1533607 - Assert the invariant that layers carrying root content scroll metadata should be inside the async zoom container. r=kats
authorBotond Ballo <botond@mozilla.com>
Wed, 13 Mar 2019 18:38:20 +0000
changeset 524772 2d47c27e5526e407d5360c4e6bc612febe90494f
parent 524771 8541dfa55436ca1ad01d3fe056832b41438ef33e
child 524773 04b7ccd07ab895cce5eeea12333a08a5f906889b
push id2032
push userffxbld-merge
push dateMon, 13 May 2019 09:36:57 +0000
treeherdermozilla-release@455c1065dcbe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1533607
milestone67.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 1533607 - Assert the invariant that layers carrying root content scroll metadata should be inside the async zoom container. r=kats Differential Revision: https://phabricator.services.mozilla.com/D23058
gfx/layers/apz/src/APZCTreeManager.cpp
--- a/gfx/layers/apz/src/APZCTreeManager.cpp
+++ b/gfx/layers/apz/src/APZCTreeManager.cpp
@@ -385,16 +385,19 @@ APZCTreeManager::UpdateHitTestingTreeImp
   // and so maintaining a list and removing APZCs that are still alive is much
   // simpler.
   ForEachNode<ReverseIterator>(mRootNode.get(),
                                [&state](HitTestingTreeNode* aNode) {
                                  state.mNodesToDestroy.AppendElement(aNode);
                                });
   mRootNode = nullptr;
   mUsingAsyncZoomContainer = false;
+  int asyncZoomContainerNestingDepth = 0;
+  bool haveMultipleAsyncZoomContainers = false;
+  bool haveRootContentOutsideAsyncZoomContainer = false;
 
   if (aRoot) {
     std::stack<gfx::TreeAutoIndent> indents;
     std::stack<AncestorTransform> ancestorTransforms;
     HitTestingTreeNode* parent = nullptr;
     HitTestingTreeNode* next = nullptr;
     LayersId layersId = aRootLayerTreeId;
     ancestorTransforms.push(AncestorTransform());
@@ -404,17 +407,26 @@ APZCTreeManager::UpdateHitTestingTreeImp
     mTreeLock.AssertCurrentThreadIn();
 
     ForEachNode<ReverseIterator>(
         aRoot,
         [&](ScrollNode aLayerMetrics) {
           mApzcTreeLog << aLayerMetrics.Name() << '\t';
 
           if (aLayerMetrics.IsAsyncZoomContainer()) {
+            if (mUsingAsyncZoomContainer) {
+              haveMultipleAsyncZoomContainers = true;
+            }
             mUsingAsyncZoomContainer = true;
+            ++asyncZoomContainerNestingDepth;
+          }
+
+          if (aLayerMetrics.Metrics().IsRootContent() &&
+              asyncZoomContainerNestingDepth == 0) {
+            haveRootContentOutsideAsyncZoomContainer = true;
           }
 
           HitTestingTreeNode* node = PrepareNodeForLayer(
               lock, aLayerMetrics, aLayerMetrics.Metrics(), layersId,
               ancestorTransforms.top(), parent, next, state);
           MOZ_ASSERT(node);
           AsyncPanZoomController* apzc = node->GetApzc();
           aLayerMetrics.SetApzc(apzc);
@@ -462,26 +474,41 @@ APZCTreeManager::UpdateHitTestingTreeImp
             layersId = *newLayersId;
           }
 
           indents.push(gfx::TreeAutoIndent(mApzcTreeLog));
           state.mParentHasPerspective.push(
               aLayerMetrics.TransformIsPerspective());
         },
         [&](ScrollNode aLayerMetrics) {
+          if (aLayerMetrics.IsAsyncZoomContainer()) {
+            --asyncZoomContainerNestingDepth;
+          }
+
           next = parent;
           parent = parent->GetParent();
           layersId = next->GetLayersId();
           ancestorTransforms.pop();
           indents.pop();
           state.mParentHasPerspective.pop();
         });
 
     mApzcTreeLog << "[end]\n";
 
+    MOZ_ASSERT(
+        !mUsingAsyncZoomContainer || !haveRootContentOutsideAsyncZoomContainer,
+        "If there is an async zoom container, all scroll nodes with root "
+        "content scroll metadata should be inside it");
+    // TODO(bug 1534459): Avoid multiple async zoom containers. They
+    // can't currently occur in production code, but that will become
+    // possible with either OOP iframes or desktop zooming (due to
+    // RDM), and will need to be guarded against.
+    // MOZ_ASSERT(!haveMultipleAsyncZoomContainers,
+    //           "Should only have one async zoom container");
+
     // If we have perspective transforms deferred to children, do another
     // walk of the tree and actually apply them to the children.
     // We can't do this "as we go" in the previous traversal, because by the
     // time we realize we need to defer a perspective transform for an APZC,
     // we may already have processed a previous layer (including children
     // found in its subtree) that shares that APZC.
     if (!state.mPerspectiveTransformsDeferredToChildren.empty()) {
       ForEachNode<ReverseIterator>(