Bug 1528743 - Move the top-layer display items inside the async zoom container. r=mstange
authorBotond Ballo <botond@mozilla.com>
Wed, 06 Mar 2019 22:51:09 +0000
changeset 520652 c5482772d73a8bea6946498f9f16ec9fdd9f9164
parent 520618 ba3dfc81120d01a3e931697d72e6bd95dad09582
child 520653 7b3b1bc4586f8f50ddb85d7d7e88780e79a7a6fb
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1528743
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 1528743 - Move the top-layer display items inside the async zoom container. r=mstange This maintains the important invariant that layers that carry scroll metadata for the RCD-RSF are inside the async zoom container. Differential Revision: https://phabricator.services.mozilla.com/D22049
layout/generic/ViewportFrame.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
--- a/layout/generic/ViewportFrame.cpp
+++ b/layout/generic/ViewportFrame.cpp
@@ -55,28 +55,16 @@ void ViewportFrame::BuildDisplayList(nsD
                       GRAPHICS_DisplayListBuilding);
 
   if (nsIFrame* kid = mFrames.FirstChild()) {
     // make the kid's BorderBackground our own. This ensures that the canvas
     // frame's background becomes our own background and therefore appears
     // below negative z-index elements.
     BuildDisplayListForChild(aBuilder, kid, aLists);
   }
-
-  nsDisplayList topLayerList;
-  BuildDisplayListForTopLayer(aBuilder, &topLayerList);
-  if (!topLayerList.IsEmpty()) {
-    // Wrap the whole top layer in a single item with maximum z-index,
-    // and append it at the very end, so that it stays at the topmost.
-    nsDisplayWrapList* wrapList =
-        MakeDisplayItem<nsDisplayWrapList>(aBuilder, this, &topLayerList);
-    wrapList->SetOverrideZIndex(
-        std::numeric_limits<decltype(wrapList->ZIndex())>::max());
-    aLists.PositionedDescendants()->AppendToTop(wrapList);
-  }
 }
 
 #ifdef DEBUG
 /**
  * Returns whether we are going to put an element in the top layer for
  * fullscreen. This function should matches the CSS rule in ua.css.
  */
 static bool ShouldInTopLayerForFullscreen(Element* aElement) {
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -63,16 +63,17 @@
 #include "gfxPrefs.h"
 #include "ScrollAnimationPhysics.h"
 #include "ScrollAnimationBezierPhysics.h"
 #include "ScrollAnimationMSDPhysics.h"
 #include "ScrollSnap.h"
 #include "UnitTransforms.h"
 #include "nsPluginFrame.h"
 #include "nsSliderFrame.h"
+#include "ViewportFrame.h"
 #include "mozilla/layers/APZCCallbackHelper.h"
 #include "mozilla/layers/AxisPhysicsModel.h"
 #include "mozilla/layers/AxisPhysicsMSDModel.h"
 #include "mozilla/layers/LayerTransactionChild.h"
 #include "mozilla/layers/ScrollLinkedEffectDetector.h"
 #include "mozilla/Unused.h"
 #include "VisualViewport.h"
 #include "LayersLogging.h"  // for Stringify
@@ -3373,16 +3374,18 @@ void ScrollFrameHelper::BuildDisplayList
           aBuilder, mOuter, visibleRect, dirtyRect);
 
       // Don't clip the scrolled child, and don't paint scrollbars/scrollcorner.
       // The scrolled frame shouldn't have its own background/border, so we
       // can just pass aLists directly.
       mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, aLists);
     }
 
+    MaybeAddTopLayerItems(aBuilder, aLists);
+
     if (addScrollBars) {
       // Add overlay scrollbars.
       AppendScrollPartsTo(aBuilder, aLists, createLayersForScrollbars, true);
     }
 
     return;
   }
 
@@ -3657,16 +3660,18 @@ void ScrollFrameHelper::BuildDisplayList
         if (mWillBuildScrollableLayer) {
           asrSetter.InsertScrollFrame(sf);
           aBuilder->SetDisablePartialUpdates(true);
         }
       }
     }
   }
 
+  MaybeAddTopLayerItems(aBuilder, set);
+
   if (willBuildAsyncZoomContainer) {
     MOZ_ASSERT(mClipAllDescendants);
 
     // Wrap all our scrolled contents in an nsDisplayAsyncZoom. This will be
     // the layer that gets scaled for APZ zooming. It does not have the
     // scrolled ASR, but it does have the composition bounds clip applied to
     // it. The children have the layout viewport clip applied to them (above).
     // Effectively we are double clipping to the viewport, at potentially
@@ -3730,16 +3735,35 @@ void ScrollFrameHelper::BuildDisplayList
 
   // Now display overlay scrollbars and the resizer, if we have one.
   AppendScrollPartsTo(aBuilder, scrolledContent, createLayersForScrollbars,
                       true);
 
   scrolledContent.MoveTo(aLists);
 }
 
+void ScrollFrameHelper::MaybeAddTopLayerItems(nsDisplayListBuilder* aBuilder,
+                                              const nsDisplayListSet& aLists) {
+  if (mIsRoot) {
+    if (ViewportFrame* viewportFrame = do_QueryFrame(mOuter->GetParent())) {
+      nsDisplayList topLayerList;
+      viewportFrame->BuildDisplayListForTopLayer(aBuilder, &topLayerList);
+      if (!topLayerList.IsEmpty()) {
+        // Wrap the whole top layer in a single item with maximum z-index,
+        // and append it at the very end, so that it stays at the topmost.
+        nsDisplayWrapList* wrapList = MakeDisplayItem<nsDisplayWrapList>(
+            aBuilder, viewportFrame, &topLayerList);
+        wrapList->SetOverrideZIndex(
+            std::numeric_limits<decltype(wrapList->ZIndex())>::max());
+        aLists.PositionedDescendants()->AppendToTop(wrapList);
+      }
+    }
+  }
+}
+
 bool ScrollFrameHelper::DecideScrollableLayer(
     nsDisplayListBuilder* aBuilder, nsRect* aVisibleRect, nsRect* aDirtyRect,
     bool aSetBase, bool* aDirtyRectHasBeenOverriden) {
   // Save and check if this changes so we can recompute the current agr.
   bool oldWillBuildScrollableLayer = mWillBuildScrollableLayer;
 
   nsIContent* content = mOuter->GetContent();
   bool usingDisplayPort = nsLayoutUtils::HasDisplayPort(content);
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -77,16 +77,28 @@ class ScrollFrameHelper : public nsIRefl
   void FireScrollEndEvent();
   void PostOverflowEvent();
   using PostDestroyData = nsIFrame::PostDestroyData;
   void Destroy(PostDestroyData& aPostDestroyData);
 
   void BuildDisplayList(nsDisplayListBuilder* aBuilder,
                         const nsDisplayListSet& aLists);
 
+  // Add display items for the top-layer (which includes things like
+  // the fullscreen element, its backdrop, and text selection carets)
+  // to |aLists|.
+  // This is a no-op for scroll frames other than the viewport's
+  // root scroll frame.
+  // This should be called with an nsDisplayListSet that will be
+  // wrapped in the async zoom container, if we're building one.
+  // It should not be called with an ASR setter on the stack, as the
+  // top-layer items handle setting up their own ASRs.
+  void MaybeAddTopLayerItems(nsDisplayListBuilder* aBuilder,
+                             const nsDisplayListSet& aLists);
+
   void AppendScrollPartsTo(nsDisplayListBuilder* aBuilder,
                            const nsDisplayListSet& aLists, bool aCreateLayer,
                            bool aPositioned);
 
   bool GetBorderRadii(const nsSize& aFrameSize, const nsSize& aBorderArea,
                       Sides aSkipSides, nscoord aRadii[8]) const;
 
   // nsIReflowCallback