Bug 1466611 - Render layout viewport on APZ minimap. r=botond
authorKashav Madan <kmadan@mozilla.com>
Mon, 04 Jun 2018 18:02:04 -0400
changeset 421464 b7ddd726b2f93b6d2da560aab18d9ce147125580
parent 421463 29081ef4774ce911f1ef8a51715cc6f463fdfeab
child 421465 ac7e4d209fb44e1c4bafbe749385195bfda6e449
push id34095
push usernbeleuzu@mozilla.com
push dateWed, 06 Jun 2018 09:35:33 +0000
treeherdermozilla-central@d51b920aef69 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond
bugs1466611
milestone62.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 1466611 - Render layout viewport on APZ minimap. r=botond MozReview-Commit-ID: HrTRZpU3rAi
gfx/layers/apz/public/APZSampler.h
gfx/layers/apz/src/APZSampler.cpp
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/apz/src/AsyncPanZoomController.h
gfx/layers/composite/ContainerLayerComposite.cpp
--- a/gfx/layers/apz/public/APZSampler.h
+++ b/gfx/layers/apz/public/APZSampler.h
@@ -76,16 +76,17 @@ public:
    */
   LayerToParentLayerMatrix4x4 ComputeTransformForScrollThumb(
       const LayerToParentLayerMatrix4x4& aCurrentTransform,
       const LayerMetricsWrapper& aContent,
       const ScrollbarData& aThumbData,
       bool aScrollbarIsDescendant,
       AsyncTransformComponentMatrix* aOutClipTransform);
 
+  CSSRect GetCurrentAsyncLayoutViewport(const LayerMetricsWrapper& aLayer);
   ParentLayerPoint GetCurrentAsyncScrollOffset(const LayerMetricsWrapper& aLayer);
   AsyncTransform GetCurrentAsyncTransform(const LayerMetricsWrapper& aLayer);
   AsyncTransformComponentMatrix GetOverscrollTransform(const LayerMetricsWrapper& aLayer);
   AsyncTransformComponentMatrix GetCurrentAsyncTransformWithOverscroll(const LayerMetricsWrapper& aLayer);
 
   void MarkAsyncTransformAppliedToContent(const LayerMetricsWrapper& aLayer);
   bool HasUnusedAsyncTransform(const LayerMetricsWrapper& aLayer);
 
--- a/gfx/layers/apz/src/APZSampler.cpp
+++ b/gfx/layers/apz/src/APZSampler.cpp
@@ -145,16 +145,26 @@ APZSampler::ComputeTransformForScrollThu
                                               aContent.GetTransform(),
                                               aContent.GetApzc(),
                                               aContent.Metrics(),
                                               aThumbData,
                                               aScrollbarIsDescendant,
                                               aOutClipTransform);
 }
 
+CSSRect
+APZSampler::GetCurrentAsyncLayoutViewport(const LayerMetricsWrapper& aLayer)
+{
+  MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
+  AssertOnSamplerThread();
+
+  MOZ_ASSERT(aLayer.GetApzc());
+  return aLayer.GetApzc()->GetCurrentAsyncLayoutViewport(AsyncPanZoomController::eForCompositing);
+}
+
 ParentLayerPoint
 APZSampler::GetCurrentAsyncScrollOffset(const LayerMetricsWrapper& aLayer)
 {
   MOZ_ASSERT(CompositorThreadHolder::IsInCompositorThread());
   AssertOnSamplerThread();
 
   MOZ_ASSERT(aLayer.GetApzc());
   return aLayer.GetApzc()->GetCurrentAsyncScrollOffset(AsyncPanZoomController::eForCompositing);
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -3726,16 +3726,27 @@ bool AsyncPanZoomController::AdvanceAnim
     APZThreadUtils::RunOnControllerThread(deferredTasks[i].forget());
   }
 
   // If any of the deferred tasks starts a new animation, it will request a
   // new composite directly, so we can just return requestAnimationFrame here.
   return requestAnimationFrame;
 }
 
+CSSRect
+AsyncPanZoomController::GetCurrentAsyncLayoutViewport(AsyncTransformConsumer aMode) const {
+  RecursiveMutexAutoLock lock(mRecursiveMutex);
+  MOZ_ASSERT(mFrameMetrics.IsRootContent(),
+      "Only the root content APZC has a layout viewport");
+  if (aMode == eForCompositing && mScrollMetadata.IsApzForceDisabled()) {
+    return mLastContentPaintMetrics.GetViewport();
+  }
+  return GetEffectiveLayoutViewport(aMode);
+}
+
 ParentLayerPoint
 AsyncPanZoomController::GetCurrentAsyncScrollOffset(AsyncTransformConsumer aMode) const
 {
   RecursiveMutexAutoLock lock(mRecursiveMutex);
 
   if (aMode == eForCompositing && mScrollMetadata.IsApzForceDisabled()) {
     return mLastContentPaintMetrics.GetScrollOffset() * mLastContentPaintMetrics.GetZoom();
   }
@@ -3797,16 +3808,25 @@ AsyncPanZoomController::GetCurrentAsyncT
 
   LayerToParentLayerScale compositedAsyncZoom =
       (effectiveZoom / mFrameMetrics.LayersPixelsPerCSSPixel()).ToScaleFactor();
   return AsyncTransform(
     LayerToParentLayerScale(compositedAsyncZoom.scale * mTestAsyncZoom.scale),
     -translation);
 }
 
+CSSRect
+AsyncPanZoomController::GetEffectiveLayoutViewport(AsyncTransformConsumer aMode) const
+{
+  if (gfxPrefs::APZFrameDelayEnabled() && aMode == eForCompositing) {
+    return mCompositedLayoutViewport;
+  }
+  return mFrameMetrics.GetViewport();
+}
+
 CSSPoint
 AsyncPanZoomController::GetEffectiveScrollOffset(AsyncTransformConsumer aMode) const
 {
   if (gfxPrefs::APZFrameDelayEnabled() && aMode == eForCompositing) {
     return mCompositedScrollOffset;
   }
   return mFrameMetrics.GetScrollOffset();
 }
@@ -3821,16 +3841,17 @@ AsyncPanZoomController::GetEffectiveZoom
 }
 
 bool
 AsyncPanZoomController::SampleCompositedAsyncTransform()
 {
   RecursiveMutexAutoLock lock(mRecursiveMutex);
   if (mCompositedScrollOffset != mFrameMetrics.GetScrollOffset() ||
       mCompositedZoom != mFrameMetrics.GetZoom()) {
+    mCompositedLayoutViewport = mFrameMetrics.GetViewport();
     mCompositedScrollOffset = mFrameMetrics.GetScrollOffset();
     mCompositedZoom = mFrameMetrics.GetZoom();
     return true;
   }
   return false;
 }
 
 AsyncTransformComponentMatrix
@@ -4079,16 +4100,17 @@ void AsyncPanZoomController::NotifyLayer
     // Initialize our internal state to something sane when the content
     // that was just painted is something we knew nothing about previously
     CancelAnimation();
 
     mScrollMetadata = aScrollMetadata;
     mExpectedGeckoMetrics = aLayerMetrics;
     ShareCompositorFrameMetrics();
 
+    mCompositedLayoutViewport = mFrameMetrics.GetViewport();
     mCompositedScrollOffset = mFrameMetrics.GetScrollOffset();
     mCompositedZoom = mFrameMetrics.GetZoom();
 
     if (mFrameMetrics.GetDisplayPortMargins() != ScreenMargin()) {
       // A non-zero display port margin here indicates a displayport has
       // been set by a previous APZC for the content at this guid. The
       // scrollable rect may have changed since then, making the margins
       // wrong, so we need to calculate a new display port.
@@ -4163,16 +4185,17 @@ void AsyncPanZoomController::NotifyLayer
       // Send an acknowledgement with the new scroll generation so that any
       // repaint requests later in this function go through.
       // Because of the scroll generation update, any inflight paint requests are
       // going to be ignored by layout, and so mExpectedGeckoMetrics
       // becomes incorrect for the purposes of calculating the LD transform. To
       // correct this we need to update mExpectedGeckoMetrics to be the
       // last thing we know was painted by Gecko.
       mFrameMetrics.CopyScrollInfoFrom(aLayerMetrics);
+      mCompositedLayoutViewport = mFrameMetrics.GetViewport();
       mCompositedScrollOffset = mFrameMetrics.GetScrollOffset();
       mExpectedGeckoMetrics = aLayerMetrics;
 
       // Cancel the animation (which might also trigger a repaint request)
       // after we update the scroll offset above. Otherwise we can be left
       // in a state where things are out of sync.
       CancelAnimation();
 
--- a/gfx/layers/apz/src/AsyncPanZoomController.h
+++ b/gfx/layers/apz/src/AsyncPanZoomController.h
@@ -903,18 +903,20 @@ private:
   FrameMetrics& mLastContentPaintMetrics;  // for convenience, refers to mLastContentPaintMetadata.mMetrics
   // The last metrics used for a content repaint request.
   FrameMetrics mLastPaintRequestMetrics;
   // The metrics that we expect content to have. This is updated when we
   // request a content repaint, and when we receive a shadow layers update.
   // This allows us to transform events into Gecko's coordinate space.
   FrameMetrics mExpectedGeckoMetrics;
 
-  // These variables cache the scroll offset and zoom stored in |mFrameMetrics|
-  // the last time SampleCompositedAsyncTransform() was called.
+  // These variables cache the layout viewport, scroll offset, and zoom stored
+  // in |mFrameMetrics| the last time SampleCompositedAsyncTransform() was
+  // called.
+  CSSRect mCompositedLayoutViewport;
   CSSPoint mCompositedScrollOffset;
   CSSToParentLayerScale2D mCompositedZoom;
 
   AxisX mX;
   AxisY mY;
 
   // This flag is set to true when we are in a axis-locked pan as a result of
   // the touch-action CSS property.
@@ -987,16 +989,22 @@ public:
    * regardless of mForceDisableApz.
    */
   enum AsyncTransformConsumer {
     eForHitTesting,
     eForCompositing,
   };
 
   /**
+   * Get the current layout viewport of the scrollable frame corresponding to
+   * this APZC.
+   */
+  CSSRect GetCurrentAsyncLayoutViewport(AsyncTransformConsumer aMode) const;
+
+  /**
    * Get the current scroll offset of the scrollable frame corresponding
    * to this APZC, including the effects of any asynchronous panning and
    * zooming, in ParentLayer pixels.
    */
   ParentLayerPoint GetCurrentAsyncScrollOffset(AsyncTransformConsumer aMode) const;
 
   /**
    * Get the current scroll offset of the scrollable frame corresponding
@@ -1036,21 +1044,22 @@ private:
    *
    * (This is only relevant when |gfxPrefs::APZFrameDelayEnabled() == true|.
    * Otherwise, GetCurrentAsyncTransform() always reflects what's stored in
    * |mFrameMetrics| immediately, without any delay.)
    */
   bool SampleCompositedAsyncTransform();
 
   /*
-   * Helper functions to query the async scroll offset and zoom either
-   * directly from |mFrameMetrics|, or from cached variables that store
-   * the scroll offset and zoom from the last time it was sampled by
-   * calling SampleCompositedAsyncTransform(), depending on who is asking.
+   * Helper functions to query the async layout viewport, scroll offset, and
+   * zoom either directly from |mFrameMetrics|, or from cached variables that
+   * store the required value from the last time it was sampled by calling
+   * SampleCompositedAsyncTransform(), depending on who is asking.
    */
+  CSSRect GetEffectiveLayoutViewport(AsyncTransformConsumer aMode) const;
   CSSPoint GetEffectiveScrollOffset(AsyncTransformConsumer aMode) const;
   CSSToParentLayerScale2D GetEffectiveZoom(AsyncTransformConsumer aMode) const;
 
   /* ===================================================================
    * The functions and members in this section are used to manage
    * the state that tracks what this APZC is doing with the input events.
    */
 protected:
--- a/gfx/layers/composite/ContainerLayerComposite.cpp
+++ b/gfx/layers/composite/ContainerLayerComposite.cpp
@@ -311,30 +311,36 @@ RenderMinimap(ContainerT* aContainer,
   const int verticalPadding = 10;
   const int horizontalPadding = 5;
   gfx::Color backgroundColor(0.3f, 0.3f, 0.3f, 0.3f);
   gfx::Color tileActiveColor(1, 1, 1, 0.4f);
   gfx::Color tileBorderColor(0, 0, 0, 0.1f);
   gfx::Color pageBorderColor(0, 0, 0);
   gfx::Color criticalDisplayPortColor(1.f, 1.f, 0);
   gfx::Color displayPortColor(0, 1.f, 0);
-  gfx::Color viewPortColor(0, 0, 1.f, 0.3f);
+  gfx::Color layoutPortColor(1.f, 0, 0);
+  gfx::Color visualPortColor(0, 0, 1.f, 0.3f);
 
   // Rects
   ParentLayerRect compositionBounds = fm.GetCompositionBounds();
   LayerRect scrollRect = fm.GetScrollableRect() * fm.LayersPixelsPerCSSPixel();
-  LayerRect viewRect = ParentLayerRect(scrollOffset, compositionBounds.Size()) / LayerToParentLayerScale(1);
+  LayerRect visualRect = ParentLayerRect(scrollOffset, compositionBounds.Size()) / LayerToParentLayerScale(1);
   LayerRect dp = (fm.GetDisplayPort() + fm.GetScrollOffset()) * fm.LayersPixelsPerCSSPixel();
+  Maybe<LayerRect> layoutRect;
   Maybe<LayerRect> cdp;
+  if (fm.IsRootContent()) {
+    CSSRect viewport = aSampler->GetCurrentAsyncLayoutViewport(wrapper);
+    layoutRect = Some(viewport * fm.LayersPixelsPerCSSPixel());
+  }
   if (!fm.GetCriticalDisplayPort().IsEmpty()) {
     cdp = Some((fm.GetCriticalDisplayPort() + fm.GetScrollOffset()) * fm.LayersPixelsPerCSSPixel());
   }
 
   // Don't render trivial minimap. They can show up from textboxes and other tiny frames.
-  if (viewRect.Width() < 64 && viewRect.Height() < 64) {
+  if (visualRect.Width() < 64 && visualRect.Height() < 64) {
     return;
   }
 
   // Compute a scale with an appropriate aspect ratio
   // We allocate up to 100px of width and the height of this layer.
   float scaleFactor;
   float scaleFactorX;
   float scaleFactorY;
@@ -369,19 +375,26 @@ RenderMinimap(ContainerT* aContainer,
   compositor->SlowDrawRect(r, displayPortColor, clipRect, aContainer->GetEffectiveTransform());
 
   // Render the critical displayport if there is one
   if (cdp) {
     r = transform.TransformBounds(cdp->ToUnknownRect());
     compositor->SlowDrawRect(r, criticalDisplayPortColor, clipRect, aContainer->GetEffectiveTransform());
   }
 
-  // Render the viewport.
-  r = transform.TransformBounds(viewRect.ToUnknownRect());
-  compositor->SlowDrawRect(r, viewPortColor, clipRect, aContainer->GetEffectiveTransform(), 2);
+  // Render the layout viewport if it exists (which is only in the root
+  // content APZC).
+  if (layoutRect) {
+    r = transform.TransformBounds(layoutRect->ToUnknownRect());
+    compositor->SlowDrawRect(r, layoutPortColor, clipRect, aContainer->GetEffectiveTransform());
+  }
+
+  // Render the visual viewport.
+  r = transform.TransformBounds(visualRect.ToUnknownRect());
+  compositor->SlowDrawRect(r, visualPortColor, clipRect, aContainer->GetEffectiveTransform(), 2);
 }
 
 template<class ContainerT> void
 RenderLayers(ContainerT* aContainer, LayerManagerComposite* aManager,
              const RenderTargetIntRect& aClipRect,
              const Maybe<gfx::Polygon>& aGeometry)
 {
   Compositor* compositor = aManager->GetCompositor();