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 521774 2d47c27e5526
parent 521773 8541dfa55436
child 521775 04b7ccd07ab8
push id10867
push userdvarga@mozilla.com
push dateThu, 14 Mar 2019 15:20:45 +0000
treeherdermozilla-beta@abad13547875 [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>(