Bug 1485834 - Allow recomputing the cumulative resolution in ComputeScrollMetadata. r=botond
authorKartikaya Gupta <kgupta@mozilla.com>
Fri, 19 Oct 2018 14:24:50 +0000
changeset 500649 b466e005ccbb79b108abb8d0083ef5a2ca928057
parent 500648 15786d06ad120f168f69966f616f3d823f1f0869
child 500650 c68fc2d0347185ab54ef90462b9b294f82cc50be
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond
bugs1485834
milestone64.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 1485834 - Allow recomputing the cumulative resolution in ComputeScrollMetadata. r=botond We need to correctly populate the cumulative resolution field in the ScrollMetadata in order to support zooming. Without this, the cumulative resolution doesn't include the presShell resolution, and that results in APZ getting into an inconsistent state. Currently, the cumulative resolution is populated from the ContainerLayerParameters object's scale, but in the case of WebRender, we call ComputeScrollMetadata with an empty ContainerLayerParameters since don't actually do layer building or rasterization in Gecko. This patch makes this more explicit by changing the argument to a Maybe<ContainerLayerParameters> and passing Nothing() from the WebRender call sites. In this scenario, we just use the cumulative presShell resolution as the cumulative resolution, which should be correct for WebRender as we won't have an "extra" CSS-derived resolution applied on the Gecko side. Depends on D9120 Differential Revision: https://phabricator.services.mozilla.com/D9121
gfx/layers/wr/ClipManager.cpp
gfx/layers/wr/WebRenderScrollData.cpp
layout/base/nsLayoutUtils.cpp
layout/base/nsLayoutUtils.h
layout/generic/nsGfxScrollFrame.cpp
layout/generic/nsGfxScrollFrame.h
layout/generic/nsIScrollableFrame.h
layout/painting/FrameLayerBuilder.cpp
layout/painting/nsDisplayList.cpp
--- a/gfx/layers/wr/ClipManager.cpp
+++ b/gfx/layers/wr/ClipManager.cpp
@@ -286,17 +286,17 @@ ClipManager::DefineScrollLayers(const Ac
   if (scrollId) {
     // If we've already defined this scroll layer before, we can early-exit
     return scrollId;
   }
   // Recurse to define the ancestors
   Maybe<wr::WrClipId> ancestorScrollId = DefineScrollLayers(aASR->mParent, aItem, aSc);
 
   Maybe<ScrollMetadata> metadata = aASR->mScrollableFrame->ComputeScrollMetadata(
-      mManager, aItem->ReferenceFrame(), ContainerLayerParameters(), nullptr);
+      mManager, aItem->ReferenceFrame(), Nothing(), nullptr);
   MOZ_ASSERT(metadata);
   FrameMetrics& metrics = metadata->GetMetrics();
 
   if (!metrics.IsScrollable()) {
     // This item is a scrolling no-op, skip over it in the ASR chain.
     return ancestorScrollId;
   }
 
--- a/gfx/layers/wr/WebRenderScrollData.cpp
+++ b/gfx/layers/wr/WebRenderScrollData.cpp
@@ -62,17 +62,17 @@ WebRenderLayerScrollData::Initialize(Web
   while (asr && asr != aStopAtAsr) {
     MOZ_ASSERT(aOwner.GetManager());
     FrameMetrics::ViewID scrollId = asr->GetViewId();
     if (Maybe<size_t> index = aOwner.HasMetadataFor(scrollId)) {
       mScrollIds.AppendElement(index.ref());
     } else {
       Maybe<ScrollMetadata> metadata = asr->mScrollableFrame->ComputeScrollMetadata(
           aOwner.GetManager(), aItem->ReferenceFrame(),
-          ContainerLayerParameters(), nullptr);
+          Nothing(), nullptr);
       MOZ_ASSERT(metadata);
       MOZ_ASSERT(metadata->GetMetrics().GetScrollId() == scrollId);
       mScrollIds.AppendElement(aOwner.AddMetadata(metadata.ref()));
     }
     asr = asr->mParent;
   }
 
   // aAncestorTransform, if present, is the transform from an ancestor
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -9166,17 +9166,17 @@ nsLayoutUtils::ComputeScrollMetadata(nsI
                                      nsIFrame* aScrollFrame,
                                      nsIContent* aContent,
                                      const nsIFrame* aReferenceFrame,
                                      LayerManager* aLayerManager,
                                      ViewID aScrollParentId,
                                      const nsRect& aViewport,
                                      const Maybe<nsRect>& aClipRect,
                                      bool aIsRootContent,
-                                     const ContainerLayerParameters& aContainerParameters)
+                                     const Maybe<ContainerLayerParameters>& aContainerParameters)
 {
   nsPresContext* presContext = aForFrame->PresContext();
   int32_t auPerDevPixel = presContext->AppUnitsPerDevPixel();
 
   nsIPresShell* presShell = presContext->GetPresShell();
   ScrollMetadata metadata;
   FrameMetrics& metrics = metadata.GetMetrics();
   metrics.SetViewport(CSSRect::FromAppUnits(aViewport));
@@ -9328,18 +9328,23 @@ nsLayoutUtils::ComputeScrollMetadata(nsI
     metrics.SetPresShellResolution(presShell->GetResolution());
   } else {
     metrics.SetPresShellResolution(1.0f);
   }
   // The cumulative resolution is the resolution at which the scroll frame's
   // content is actually rendered. It includes the pres shell resolutions of
   // all the pres shells from here up to the root, as well as any css-driven
   // resolution. We don't need to compute it as it's already stored in the
-  // container parameters.
-  metrics.SetCumulativeResolution(aContainerParameters.Scale());
+  // container parameters... except if we're in WebRender in which case we
+  // don't have a aContainerParameters. In that case we're also not rasterizing
+  // in Gecko anyway, so the only resolution we care about here is the presShell
+  // resolution which we need to propagate to WebRender.
+  metrics.SetCumulativeResolution(aContainerParameters
+      ? aContainerParameters->Scale()
+      : LayoutDeviceToLayerScale2D(LayoutDeviceToLayerScale(presShell->GetCumulativeResolution())));
 
   LayoutDeviceToScreenScale2D resolutionToScreen(
       presShell->GetCumulativeResolution()
     * nsLayoutUtils::GetTransformToAncestorScale(aScrollFrame ? aScrollFrame : aForFrame));
   metrics.SetExtraResolution(metrics.GetCumulativeResolution() / resolutionToScreen);
 
   metrics.SetDevPixelsPerCSSPixel(presContext->CSSToDevPixelScale());
 
@@ -9497,17 +9502,17 @@ nsLayoutUtils::GetRootMetadata(nsDisplay
   if (addMetrics || ensureMetricsForRootId) {
     bool isRootContent = presContext->IsRootContentDocument();
 
     nsRect viewport(aBuilder->ToReferenceFrame(frame), frame->GetSize());
     return Some(nsLayoutUtils::ComputeScrollMetadata(frame,
                            rootScrollFrame, content,
                            aBuilder->FindReferenceFrameFor(frame),
                            aLayerManager, FrameMetrics::NULL_SCROLL_ID, viewport, Nothing(),
-                           isRootContent, aContainerParameters));
+                           isRootContent, Some(aContainerParameters)));
   }
 
   return Nothing();
 }
 
 /* static */ bool
 nsLayoutUtils::ContainsMetricsWithId(const Layer* aLayer, const ViewID& aScrollId)
 {
--- a/layout/base/nsLayoutUtils.h
+++ b/layout/base/nsLayoutUtils.h
@@ -2897,17 +2897,17 @@ public:
                                               nsIFrame* aScrollFrame,
                                               nsIContent* aContent,
                                               const nsIFrame* aReferenceFrame,
                                               mozilla::layers::LayerManager* aLayerManager,
                                               ViewID aScrollParentId,
                                               const nsRect& aViewport,
                                               const mozilla::Maybe<nsRect>& aClipRect,
                                               bool aIsRoot,
-                                              const ContainerLayerParameters& aContainerParameters);
+                                              const mozilla::Maybe<ContainerLayerParameters>& aContainerParameters);
 
   /**
    * Returns the metadata to put onto the root layer of a layer tree, if one is
    * needed. The last argument is a callback function to check if the caller
    * already has a metadata for a given scroll id.
    */
   static mozilla::Maybe<ScrollMetadata> GetRootMetadata(nsDisplayListBuilder* aBuilder,
                                                         mozilla::layers::LayerManager* aLayerManager,
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -3953,17 +3953,17 @@ ScrollFrameHelper::DecideScrollableLayer
 
   return mWillBuildScrollableLayer;
 }
 
 
 Maybe<ScrollMetadata>
 ScrollFrameHelper::ComputeScrollMetadata(LayerManager* aLayerManager,
                                          const nsIFrame* aContainerReferenceFrame,
-                                         const ContainerLayerParameters& aParameters,
+                                         const Maybe<ContainerLayerParameters>& aParameters,
                                          const DisplayItemClip* aClip) const
 {
   if (!mWillBuildScrollableLayer || mIsScrollableLayerInRootContainer) {
     return Nothing();
   }
 
   if (!nsLayoutUtils::UsesAsyncScrolling(mOuter)) {
     // Return early, since if we don't use APZ we don't need FrameMetrics.
--- a/layout/generic/nsGfxScrollFrame.h
+++ b/layout/generic/nsGfxScrollFrame.h
@@ -462,17 +462,17 @@ public:
       mLastScrollOrigin = nullptr;
       mLastSmoothScrollOrigin = nullptr;
     }
   }
   bool WantAsyncScroll() const;
   Maybe<mozilla::layers::ScrollMetadata> ComputeScrollMetadata(
     LayerManager* aLayerManager,
     const nsIFrame* aContainerReferenceFrame,
-    const ContainerLayerParameters& aParameters,
+    const Maybe<ContainerLayerParameters>& aParameters,
     const mozilla::DisplayItemClip* aClip) const;
   void ClipLayerToDisplayPort(Layer* aLayer,
                               const mozilla::DisplayItemClip* aClip,
                               const ContainerLayerParameters& aParameters) const;
 
   // nsIScrollbarMediator
   void ScrollByPage(nsScrollbarFrame* aScrollbar, int32_t aDirection,
                     nsIScrollbarMediator::ScrollSnapMode aSnap
@@ -980,17 +980,17 @@ public:
     mHelper.ResetScrollInfoIfGeneration(aGeneration);
   }
   virtual bool WantAsyncScroll() const override {
     return mHelper.WantAsyncScroll();
   }
   virtual mozilla::Maybe<mozilla::layers::ScrollMetadata> ComputeScrollMetadata(
     LayerManager* aLayerManager,
     const nsIFrame* aContainerReferenceFrame,
-    const ContainerLayerParameters& aParameters,
+    const Maybe<ContainerLayerParameters>& aParameters,
     const mozilla::DisplayItemClip* aClip) const override
   {
     return mHelper.ComputeScrollMetadata(aLayerManager, aContainerReferenceFrame, aParameters, aClip);
   }
   virtual void ClipLayerToDisplayPort(Layer* aLayer,
                                       const mozilla::DisplayItemClip* aClip,
                                       const ContainerLayerParameters& aParameters) const override
   {
@@ -1431,17 +1431,17 @@ public:
     mHelper.ResetScrollInfoIfGeneration(aGeneration);
   }
   virtual bool WantAsyncScroll() const override {
     return mHelper.WantAsyncScroll();
   }
   virtual mozilla::Maybe<mozilla::layers::ScrollMetadata> ComputeScrollMetadata(
     LayerManager* aLayerManager,
     const nsIFrame* aContainerReferenceFrame,
-    const ContainerLayerParameters& aParameters,
+    const Maybe<ContainerLayerParameters>& aParameters,
     const mozilla::DisplayItemClip* aClip) const override
   {
     return mHelper.ComputeScrollMetadata(aLayerManager, aContainerReferenceFrame, aParameters, aClip);
   }
   virtual void ClipLayerToDisplayPort(Layer* aLayer,
                                       const mozilla::DisplayItemClip* aClip,
                                       const ContainerLayerParameters& aParameters) const override {
     mHelper.ClipLayerToDisplayPort(aLayer, aClip, aParameters);
--- a/layout/generic/nsIScrollableFrame.h
+++ b/layout/generic/nsIScrollableFrame.h
@@ -420,17 +420,17 @@ public:
    */
   virtual bool WantAsyncScroll() const = 0;
   /**
    * Returns the ScrollMetadata contributed by this frame, if there is one.
    */
   virtual mozilla::Maybe<mozilla::layers::ScrollMetadata> ComputeScrollMetadata(
     mozilla::layers::LayerManager* aLayerManager,
     const nsIFrame* aContainerReferenceFrame,
-    const ContainerLayerParameters& aParameters,
+    const mozilla::Maybe<ContainerLayerParameters>& aParameters,
     const mozilla::DisplayItemClip* aClip) const = 0;
   /**
    * Ensure's aLayer is clipped to the display port.
    */
   virtual void ClipLayerToDisplayPort(mozilla::layers::Layer* aLayer,
                                       const mozilla::DisplayItemClip* aClip,
                                       const ContainerLayerParameters& aParameters) const = 0;
 
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -6155,17 +6155,17 @@ ContainerState::SetupScrollingMetadata(N
     scrollFrame->ClipLayerToDisplayPort(aEntry->mLayer, clip, mParameters);
 
     Maybe<ScrollMetadata> metadata;
     if (mCachedScrollMetadata.mASR == asr &&
         mCachedScrollMetadata.mClip == clip) {
       metadata = mCachedScrollMetadata.mMetadata;
     } else {
       metadata = scrollFrame->ComputeScrollMetadata(
-        aEntry->mLayer->Manager(), mContainerReferenceFrame, mParameters, clip);
+        aEntry->mLayer->Manager(), mContainerReferenceFrame, Some(mParameters), clip);
       mCachedScrollMetadata.mASR = asr;
       mCachedScrollMetadata.mClip = clip;
       mCachedScrollMetadata.mMetadata = metadata;
     }
 
     if (!metadata) {
       continue;
     }
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -7179,17 +7179,17 @@ nsDisplaySubDocument::ComputeScrollMetad
                                          rootScrollFrame,
                                          rootScrollFrame->GetContent(),
                                          ReferenceFrame(),
                                          aLayerManager,
                                          mScrollParentId,
                                          viewport,
                                          Nothing(),
                                          isRootContentDocument,
-                                         params));
+                                         Some(params)));
 }
 
 static bool
 UseDisplayPortForViewport(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
 {
   return aBuilder->IsPaintingToWindow() &&
          nsLayoutUtils::ViewportHasDisplayPort(aFrame->PresContext());
 }
@@ -7870,17 +7870,17 @@ nsDisplayScrollInfoLayer::ComputeScrollM
                                          mScrollFrame,
                                          mScrollFrame->GetContent(),
                                          ReferenceFrame(),
                                          aLayerManager,
                                          mScrollParentId,
                                          viewport,
                                          Nothing(),
                                          false,
-                                         aContainerParameters);
+                                         Some(aContainerParameters));
   metadata.GetMetrics().SetIsScrollInfoLayer(true);
 
   return UniquePtr<ScrollMetadata>(new ScrollMetadata(metadata));
 }
 
 bool
 nsDisplayScrollInfoLayer::UpdateScrollData(
   mozilla::layers::WebRenderScrollData* aData,