Bug 1443792 - Remove direct access to AsyncPanZoomController from AsyncCompositionManager. r?botond draft
authorKartikaya Gupta <kgupta@mozilla.com>
Fri, 09 Mar 2018 16:54:32 -0500
changeset 765582 86a6da21dc48b37bc0d960cddf2860e6323492f0
parent 765581 1286730cf0b8afce604cf815618d1f5e560d9481
child 765583 7f4d49b753dd589aabda47511dfcaae81e248d2c
push id102110
push userkgupta@mozilla.com
push dateFri, 09 Mar 2018 21:55:02 +0000
reviewersbotond
bugs1443792
milestone60.0a1
Bug 1443792 - Remove direct access to AsyncPanZoomController from AsyncCompositionManager. r?botond MozReview-Commit-ID: 3clTOYfpV64
gfx/layers/apz/public/APZSampler.h
gfx/layers/apz/src/APZSampler.cpp
gfx/layers/composite/AsyncCompositionManager.cpp
gfx/layers/composite/AsyncCompositionManager.h
--- a/gfx/layers/apz/public/APZSampler.h
+++ b/gfx/layers/apz/public/APZSampler.h
@@ -4,16 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef mozilla_layers_APZSampler_h
 #define mozilla_layers_APZSampler_h
 
 #include "LayersTypes.h"
 #include "mozilla/layers/APZTestData.h"
+#include "mozilla/layers/AsyncCompositionManager.h" // for AsyncTransform
 #include "mozilla/Maybe.h"
 #include "nsTArray.h"
 #include "Units.h"
 
 namespace mozilla {
 
 class TimeStamp;
 
@@ -79,16 +80,21 @@ public:
 
   LayerToParentLayerMatrix4x4 ComputeTransformForScrollThumb(
       const LayerToParentLayerMatrix4x4& aCurrentTransform,
       const LayerMetricsWrapper& aContent,
       const ScrollThumbData& aThumbData,
       bool aScrollbarIsDescendant,
       AsyncTransformComponentMatrix* aOutClipTransform);
 
+  AsyncTransform GetCurrentAsyncTransform(const LayerMetricsWrapper& aLayer);
+  AsyncTransformComponentMatrix GetOverscrollTransform(const LayerMetricsWrapper& aLayer);
+
+  void MarkAsyncTransformAppliedToContent(const LayerMetricsWrapper& aLayer);
+
 protected:
   virtual ~APZSampler();
 
 private:
   RefPtr<APZCTreeManager> mApz;
 };
 
 } // namespace layers
--- a/gfx/layers/apz/src/APZSampler.cpp
+++ b/gfx/layers/apz/src/APZSampler.cpp
@@ -161,10 +161,28 @@ APZSampler::ComputeTransformForScrollThu
                                               aContent.GetTransform(),
                                               aContent.GetApzc(),
                                               aContent.Metrics(),
                                               aThumbData,
                                               aScrollbarIsDescendant,
                                               aOutClipTransform);
 }
 
+AsyncTransform
+APZSampler::GetCurrentAsyncTransform(const LayerMetricsWrapper& aLayer)
+{
+  return aLayer.GetApzc()->GetCurrentAsyncTransform(AsyncPanZoomController::eForCompositing);
+}
+
+AsyncTransformComponentMatrix
+APZSampler::GetOverscrollTransform(const LayerMetricsWrapper& aLayer)
+{
+  return aLayer.GetApzc()->GetOverscrollTransform(AsyncPanZoomController::eForCompositing);
+}
+
+void
+APZSampler::MarkAsyncTransformAppliedToContent(const LayerMetricsWrapper& aLayer)
+{
+  aLayer.GetApzc()->MarkAsyncTransformAppliedToContent();
+}
+
 } // namespace layers
 } // namespace mozilla
--- a/gfx/layers/composite/AsyncCompositionManager.cpp
+++ b/gfx/layers/composite/AsyncCompositionManager.cpp
@@ -1,17 +1,16 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "mozilla/layers/AsyncCompositionManager.h"
 #include <stdint.h>                     // for uint32_t
-#include "apz/src/AsyncPanZoomController.h"
 #include "FrameMetrics.h"               // for FrameMetrics
 #include "LayerManagerComposite.h"      // for LayerManagerComposite, etc
 #include "Layers.h"                     // for Layer, ContainerLayer, etc
 #include "gfxPoint.h"                   // for gfxPoint, gfxSize
 #include "gfxPrefs.h"                   // for gfxPrefs
 #include "mozilla/StyleAnimationValue.h" // for StyleAnimationValue, etc
 #include "mozilla/WidgetUtils.h"        // for ComputeTransformForRotation
 #include "mozilla/gfx/BaseRect.h"       // for BaseRect
@@ -703,18 +702,17 @@ AsyncCompositionManager::RecordShadowTra
   MOZ_ASSERT(gfxPrefs::CollectScrollTransforms());
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
 
   ForEachNodePostOrder<ForwardIterator>(
       aLayer,
       [this] (Layer* layer)
       {
         for (uint32_t i = 0; i < layer->GetScrollMetadataCount(); i++) {
-          AsyncPanZoomController* apzc = layer->GetAsyncPanZoomController(i);
-          if (!apzc) {
+          if (!layer->GetFrameMetrics(i).IsScrollable()) {
             continue;
           }
           gfx::Matrix4x4 shadowTransform = layer->AsHostLayer()->GetShadowBaseTransform();
           if (!shadowTransform.Is2D()) {
             continue;
           }
 
           Matrix transform = shadowTransform.As2D();
@@ -880,154 +878,156 @@ AsyncCompositionManager::ApplyAsyncConte
         // which is moved by all async scrolls on this layer.
         if (const Maybe<LayerClip>& scrolledClip = layer->GetScrolledClip()) {
           if (scrolledClip->GetMaskLayerIndex()) {
             ancestorMaskLayers.AppendElement(
                 layer->GetAncestorMaskLayerAt(*scrolledClip->GetMaskLayerIndex()));
           }
         }
 
-        for (uint32_t i = 0; i < layer->GetScrollMetadataCount(); i++) {
-          AsyncPanZoomController* controller = layer->GetAsyncPanZoomController(i);
-          if (!controller) {
-            continue;
-          }
+        if (RefPtr<APZSampler> sampler = mCompositorBridge->GetAPZSampler()) {
+          for (uint32_t i = 0; i < layer->GetScrollMetadataCount(); i++) {
+            LayerMetricsWrapper wrapper(layer, i);
+            const FrameMetrics& metrics = wrapper.Metrics();
+            if (!metrics.IsScrollable()) {
+              continue;
+            }
 
-          hasAsyncTransform = true;
+            hasAsyncTransform = true;
 
-          AsyncTransform asyncTransformWithoutOverscroll =
-              controller->GetCurrentAsyncTransform(AsyncPanZoomController::eForCompositing);
-          AsyncTransformComponentMatrix overscrollTransform =
-              controller->GetOverscrollTransform(AsyncPanZoomController::eForCompositing);
-          AsyncTransformComponentMatrix asyncTransform =
-              AsyncTransformComponentMatrix(asyncTransformWithoutOverscroll)
-            * overscrollTransform;
+            AsyncTransform asyncTransformWithoutOverscroll =
+                sampler->GetCurrentAsyncTransform(wrapper);
+            AsyncTransformComponentMatrix overscrollTransform =
+                sampler->GetOverscrollTransform(wrapper);
+            AsyncTransformComponentMatrix asyncTransform =
+                AsyncTransformComponentMatrix(asyncTransformWithoutOverscroll)
+              * overscrollTransform;
 
-          if (!layer->IsScrollableWithoutContent()) {
-            controller->MarkAsyncTransformAppliedToContent();
-          }
+            if (!layer->IsScrollableWithoutContent()) {
+              sampler->MarkAsyncTransformAppliedToContent(wrapper);
+            }
 
-          const ScrollMetadata& scrollMetadata = layer->GetScrollMetadata(i);
-          const FrameMetrics& metrics = scrollMetadata.GetMetrics();
+            const ScrollMetadata& scrollMetadata = wrapper.Metadata();
 
 #if defined(MOZ_WIDGET_ANDROID)
-          // If we find a metrics which is the root content doc, use that. If not, use
-          // the root layer. Since this function recurses on children first we should
-          // only end up using the root layer if the entire tree was devoid of a
-          // root content metrics. This is a temporary solution; in the long term we
-          // should not need the root content metrics at all. See bug 1201529 comment
-          // 6 for details.
-          if (!(*aOutFoundRoot)) {
-            *aOutFoundRoot = metrics.IsRootContent() ||       /* RCD */
-                  (layer->GetParent() == nullptr &&          /* rootmost metrics */
-                   i + 1 >= layer->GetScrollMetadataCount());
-            if (*aOutFoundRoot) {
-              mRootScrollableId = metrics.GetScrollId();
-              Compositor* compositor = mLayerManager->GetCompositor();
-              if (CompositorBridgeParent* bridge = compositor->GetCompositorBridgeParent()) {
-                AndroidDynamicToolbarAnimator* animator = bridge->GetAndroidDynamicToolbarAnimator();
-                MOZ_ASSERT(animator);
-                if (mIsFirstPaint) {
-                  animator->UpdateRootFrameMetrics(metrics);
-                  animator->FirstPaint();
-                  mIsFirstPaint = false;
+            // If we find a metrics which is the root content doc, use that. If not, use
+            // the root layer. Since this function recurses on children first we should
+            // only end up using the root layer if the entire tree was devoid of a
+            // root content metrics. This is a temporary solution; in the long term we
+            // should not need the root content metrics at all. See bug 1201529 comment
+            // 6 for details.
+            if (!(*aOutFoundRoot)) {
+              *aOutFoundRoot = metrics.IsRootContent() ||       /* RCD */
+                    (layer->GetParent() == nullptr &&          /* rootmost metrics */
+                     i + 1 >= layer->GetScrollMetadataCount());
+              if (*aOutFoundRoot) {
+                mRootScrollableId = metrics.GetScrollId();
+                Compositor* compositor = mLayerManager->GetCompositor();
+                if (CompositorBridgeParent* bridge = compositor->GetCompositorBridgeParent()) {
+                  AndroidDynamicToolbarAnimator* animator = bridge->GetAndroidDynamicToolbarAnimator();
+                  MOZ_ASSERT(animator);
+                  if (mIsFirstPaint) {
+                    animator->UpdateRootFrameMetrics(metrics);
+                    animator->FirstPaint();
+                    mIsFirstPaint = false;
+                  }
+                  if (mLayersUpdated) {
+                    animator->NotifyLayersUpdated();
+                    mLayersUpdated = false;
+                  }
+                  // If this is not actually the root content then the animator is not getting updated in AsyncPanZoomController::NotifyLayersUpdated
+                  // because the root content document is not scrollable. So update it here so it knows if the root composition size has changed.
+                  if (!metrics.IsRootContent()) {
+                    animator->MaybeUpdateCompositionSizeAndRootFrameMetrics(metrics);
+                  }
                 }
-                if (mLayersUpdated) {
-                  animator->NotifyLayersUpdated();
-                  mLayersUpdated = false;
-                }
-                // If this is not actually the root content then the animator is not getting updated in AsyncPanZoomController::NotifyLayersUpdated
-                // because the root content document is not scrollable. So update it here so it knows if the root composition size has changed.
-                if (!metrics.IsRootContent()) {
-                  animator->MaybeUpdateCompositionSizeAndRootFrameMetrics(metrics);
-                }
+                fixedLayerMargins = mFixedLayerMargins;
               }
-              fixedLayerMargins = mFixedLayerMargins;
             }
-          }
 #else
-          *aOutFoundRoot = false;
-          // Non-Android platforms still care about this flag being cleared after
-          // the first call to TransformShadowTree().
-          mIsFirstPaint = false;
+            *aOutFoundRoot = false;
+            // Non-Android platforms still care about this flag being cleared after
+            // the first call to TransformShadowTree().
+            mIsFirstPaint = false;
 #endif
 
-          // Transform the current local clips by this APZC's async transform. If we're
-          // using containerful scrolling, then the clip is not part of the scrolled
-          // frame and should not be transformed.
-          if (!scrollMetadata.UsesContainerScrolling()) {
-            MOZ_ASSERT(asyncTransform.Is2D());
-            if (clipParts.mFixedClip) {
-              *clipParts.mFixedClip = TransformBy(asyncTransform, *clipParts.mFixedClip);
+            // Transform the current local clips by this APZC's async transform. If we're
+            // using containerful scrolling, then the clip is not part of the scrolled
+            // frame and should not be transformed.
+            if (!scrollMetadata.UsesContainerScrolling()) {
+              MOZ_ASSERT(asyncTransform.Is2D());
+              if (clipParts.mFixedClip) {
+                *clipParts.mFixedClip = TransformBy(asyncTransform, *clipParts.mFixedClip);
+              }
+              if (clipParts.mScrolledClip) {
+                *clipParts.mScrolledClip = TransformBy(asyncTransform, *clipParts.mScrolledClip);
+              }
             }
-            if (clipParts.mScrolledClip) {
-              *clipParts.mScrolledClip = TransformBy(asyncTransform, *clipParts.mScrolledClip);
-            }
-          }
-          // Note: we don't set the layer's shadow clip rect property yet;
-          // AlignFixedAndStickyLayers will use the clip parts from the clip parts
-          // cache.
+            // Note: we don't set the layer's shadow clip rect property yet;
+            // AlignFixedAndStickyLayers will use the clip parts from the clip parts
+            // cache.
 
-          combinedAsyncTransform *= asyncTransform;
+            combinedAsyncTransform *= asyncTransform;
 
-          // For the purpose of aligning fixed and sticky layers, we disregard
-          // the overscroll transform as well as any OMTA transform when computing the
-          // 'aCurrentTransformForRoot' parameter. This ensures that the overscroll
-          // and OMTA transforms are not unapplied, and therefore that the visual
-          // effects apply to fixed and sticky layers. We do this by using
-          // GetTransform() as the base transform rather than GetLocalTransform(),
-          // which would include those factors.
-          LayerToParentLayerMatrix4x4 transformWithoutOverscrollOrOmta =
-              layer->GetTransformTyped()
-            * CompleteAsyncTransform(
-                AdjustForClip(asyncTransformWithoutOverscroll, layer));
+            // For the purpose of aligning fixed and sticky layers, we disregard
+            // the overscroll transform as well as any OMTA transform when computing the
+            // 'aCurrentTransformForRoot' parameter. This ensures that the overscroll
+            // and OMTA transforms are not unapplied, and therefore that the visual
+            // effects apply to fixed and sticky layers. We do this by using
+            // GetTransform() as the base transform rather than GetLocalTransform(),
+            // which would include those factors.
+            LayerToParentLayerMatrix4x4 transformWithoutOverscrollOrOmta =
+                layer->GetTransformTyped()
+              * CompleteAsyncTransform(
+                  AdjustForClip(asyncTransformWithoutOverscroll, layer));
 
-          AlignFixedAndStickyLayers(layer, layer, metrics.GetScrollId(), oldTransform,
-                                    transformWithoutOverscrollOrOmta, fixedLayerMargins,
-                                    &clipPartsCache);
+            AlignFixedAndStickyLayers(layer, layer, metrics.GetScrollId(), oldTransform,
+                                      transformWithoutOverscrollOrOmta, fixedLayerMargins,
+                                      &clipPartsCache);
 
-          // Combine the local clip with the ancestor scrollframe clip. This is not
-          // included in the async transform above, since the ancestor clip should not
-          // move with this APZC.
-          if (scrollMetadata.HasScrollClip()) {
-            ParentLayerIntRect clip = scrollMetadata.ScrollClip().GetClipRect();
-            if (layer->GetParent() && layer->GetParent()->GetTransformIsPerspective()) {
-              // If our parent layer has a perspective transform, we want to apply
-              // our scroll clip to it instead of to this layer (see bug 1168263).
-              // A layer with a perspective transform shouldn't have multiple
-              // children with FrameMetrics, nor a child with multiple FrameMetrics.
-              // (A child with multiple FrameMetrics would mean that there's *another*
-              // scrollable element between the one with the CSS perspective and the
-              // transformed element. But you'd have to use preserve-3d on the inner
-              // scrollable element in order to have the perspective apply to the
-              // transformed child, and preserve-3d is not supported on scrollable
-              // elements, so this case can't occur.)
-              MOZ_ASSERT(!stackDeferredClips.top());
-              stackDeferredClips.top().emplace(clip);
-            } else {
-              clipParts.mScrolledClip = IntersectMaybeRects(Some(clip),
-                  clipParts.mScrolledClip);
+            // Combine the local clip with the ancestor scrollframe clip. This is not
+            // included in the async transform above, since the ancestor clip should not
+            // move with this APZC.
+            if (scrollMetadata.HasScrollClip()) {
+              ParentLayerIntRect clip = scrollMetadata.ScrollClip().GetClipRect();
+              if (layer->GetParent() && layer->GetParent()->GetTransformIsPerspective()) {
+                // If our parent layer has a perspective transform, we want to apply
+                // our scroll clip to it instead of to this layer (see bug 1168263).
+                // A layer with a perspective transform shouldn't have multiple
+                // children with FrameMetrics, nor a child with multiple FrameMetrics.
+                // (A child with multiple FrameMetrics would mean that there's *another*
+                // scrollable element between the one with the CSS perspective and the
+                // transformed element. But you'd have to use preserve-3d on the inner
+                // scrollable element in order to have the perspective apply to the
+                // transformed child, and preserve-3d is not supported on scrollable
+                // elements, so this case can't occur.)
+                MOZ_ASSERT(!stackDeferredClips.top());
+                stackDeferredClips.top().emplace(clip);
+              } else {
+                clipParts.mScrolledClip = IntersectMaybeRects(Some(clip),
+                    clipParts.mScrolledClip);
+              }
             }
-          }
+
+            // Do the same for the ancestor mask layers: ancestorMaskLayers contains
+            // the ancestor mask layers for scroll frames *inside* the current scroll
+            // frame, so these are the ones we need to shift by our async transform.
+            for (Layer* ancestorMaskLayer : ancestorMaskLayers) {
+              SetShadowTransform(ancestorMaskLayer,
+                  ancestorMaskLayer->GetLocalTransformTyped() * asyncTransform);
+            }
 
-          // Do the same for the ancestor mask layers: ancestorMaskLayers contains
-          // the ancestor mask layers for scroll frames *inside* the current scroll
-          // frame, so these are the ones we need to shift by our async transform.
-          for (Layer* ancestorMaskLayer : ancestorMaskLayers) {
-            SetShadowTransform(ancestorMaskLayer,
-                ancestorMaskLayer->GetLocalTransformTyped() * asyncTransform);
-          }
-
-          // Append the ancestor mask layer for this scroll frame to ancestorMaskLayers.
-          if (scrollMetadata.HasScrollClip()) {
-            const LayerClip& scrollClip = scrollMetadata.ScrollClip();
-            if (scrollClip.GetMaskLayerIndex()) {
-              size_t maskLayerIndex = scrollClip.GetMaskLayerIndex().value();
-              Layer* ancestorMaskLayer = layer->GetAncestorMaskLayerAt(maskLayerIndex);
-              ancestorMaskLayers.AppendElement(ancestorMaskLayer);
+            // Append the ancestor mask layer for this scroll frame to ancestorMaskLayers.
+            if (scrollMetadata.HasScrollClip()) {
+              const LayerClip& scrollClip = scrollMetadata.ScrollClip();
+              if (scrollClip.GetMaskLayerIndex()) {
+                size_t maskLayerIndex = scrollClip.GetMaskLayerIndex().value();
+                Layer* ancestorMaskLayer = layer->GetAncestorMaskLayerAt(maskLayerIndex);
+                ancestorMaskLayers.AppendElement(ancestorMaskLayer);
+              }
             }
           }
         }
 
         bool clipChanged = (hasAsyncTransform || clipDeferredFromChildren ||
                             layer->GetScrolledClipRect());
         if (clipChanged) {
           // Intersect the two clip parts and apply them to the layer.
@@ -1064,21 +1064,20 @@ AsyncCompositionManager::ApplyAsyncConte
       });
 
   return appliedTransform;
 }
 
 static bool
 LayerIsScrollbarTarget(const LayerMetricsWrapper& aTarget, Layer* aScrollbar)
 {
-  AsyncPanZoomController* apzc = aTarget.GetApzc();
-  if (!apzc) {
+  const FrameMetrics& metrics = aTarget.Metrics();
+  if (!metrics.IsScrollable()) {
     return false;
   }
-  const FrameMetrics& metrics = aTarget.Metrics();
   if (metrics.GetScrollId() != aScrollbar->GetScrollbarTargetContainerId()) {
     return false;
   }
   return !metrics.IsScrollInfoLayer();
 }
 
 static void
 ApplyAsyncTransformToScrollbarForContent(const RefPtr<APZSampler>& aSampler,
--- a/gfx/layers/composite/AsyncCompositionManager.h
+++ b/gfx/layers/composite/AsyncCompositionManager.h
@@ -19,17 +19,16 @@
 #include "mozilla/layers/FrameUniformityData.h" // For FrameUniformityData
 #include "mozilla/layers/LayersMessages.h"  // for TargetConfig
 #include "mozilla/RefPtr.h"                   // for nsRefPtr
 #include "nsISupportsImpl.h"            // for LayerManager::AddRef, etc
 
 namespace mozilla {
 namespace layers {
 
-class AsyncPanZoomController;
 class Layer;
 class LayerManagerComposite;
 class AutoResolveRefLayers;
 class CompositorBridgeParent;
 
 // Represents async transforms consisting of a scale and a translation.
 struct AsyncTransform {
   explicit AsyncTransform(LayerToParentLayerScale aScale = LayerToParentLayerScale(),