Bug 1495055 - Adjust the composited layout viewport in AdjustScrollForSurfaceShift(). r=kats
authorBotond Ballo <botond@mozilla.com>
Thu, 11 Oct 2018 05:58:13 +0000
changeset 496528 3445b06f9ae970db3ab0ffbb845705fe831d4e9c
parent 496527 604682f515cccc13d4b4dba57928210ada4a3e40
child 496529 16aba5eca40ab337711f931f3b3140eba02c4c6f
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats
bugs1495055
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 1495055 - Adjust the composited layout viewport in AdjustScrollForSurfaceShift(). r=kats Depends on D7368 Differential Revision: https://phabricator.services.mozilla.com/D7369
gfx/layers/FrameMetrics.cpp
gfx/layers/FrameMetrics.h
gfx/layers/apz/src/AsyncPanZoomController.cpp
--- a/gfx/layers/FrameMetrics.cpp
+++ b/gfx/layers/FrameMetrics.cpp
@@ -14,67 +14,75 @@ namespace layers {
 const FrameMetrics::ViewID FrameMetrics::NULL_SCROLL_ID = 0;
 
 void
 FrameMetrics::RecalculateViewportOffset()
 {
   if (!mIsRootContent) {
     return;
   }
-  CSSRect visualViewport = GetVisualViewport();
+  KeepLayoutViewportEnclosingVisualViewport(GetVisualViewport(), mViewport);
+}
+
+/* static */ void
+FrameMetrics::KeepLayoutViewportEnclosingVisualViewport(
+    const CSSRect& aVisualViewport,
+    CSSRect& aLayoutViewport)
+{
   // If the visual viewport is contained within the layout viewport, we don't
   // need to make any adjustments, so we can exit early.
   //
   // Additionally, if the composition bounds changes (due to an orientation
-  // change, window resize, etc.), it may take a few frames for mViewport to
+  // change, window resize, etc.), it may take a few frames for aLayoutViewport to
   // update and during that time, the visual viewport may be larger than the
   // layout viewport. In such situations, we take an early exit if the visual
   // viewport contains the layout viewport.
-  if (mViewport.Contains(visualViewport) || visualViewport.Contains(mViewport)) {
+  if (aLayoutViewport.Contains(aVisualViewport) || aVisualViewport.Contains(aLayoutViewport)) {
     return;
   }
 
   // If visual viewport size is greater than the layout viewport, move the layout
   // viewport such that it remains inside the visual viewport. Otherwise,
   // move the layout viewport such that the visual viewport is contained
   // inside the layout viewport.
-  if ((mViewport.Width() < visualViewport.Width() &&
-        !FuzzyEqualsMultiplicative(mViewport.Width(), visualViewport.Width())) ||
-       (mViewport.Height() < visualViewport.Height() &&
-        !FuzzyEqualsMultiplicative(mViewport.Height(), visualViewport.Height()))) {
+  if ((aLayoutViewport.Width() < aVisualViewport.Width() &&
+        !FuzzyEqualsMultiplicative(aLayoutViewport.Width(), aVisualViewport.Width())) ||
+       (aLayoutViewport.Height() < aVisualViewport.Height() &&
+        !FuzzyEqualsMultiplicative(aLayoutViewport.Height(), aVisualViewport.Height()))) {
 
-     if (mViewport.X() < visualViewport.X()) {
+     if (aLayoutViewport.X() < aVisualViewport.X()) {
         // layout viewport moves right
-        mViewport.MoveToX(visualViewport.X());
-     } else if (visualViewport.XMost() < mViewport.XMost()) {
+        aLayoutViewport.MoveToX(aVisualViewport.X());
+     } else if (aVisualViewport.XMost() < aLayoutViewport.XMost()) {
         // layout viewport moves left
-        mViewport.MoveByX(visualViewport.XMost() - mViewport.XMost());
+        aLayoutViewport.MoveByX(aVisualViewport.XMost() - aLayoutViewport.XMost());
      }
-     if (mViewport.Y() < visualViewport.Y()) {
+     if (aLayoutViewport.Y() < aVisualViewport.Y()) {
         // layout viewport moves down
-        mViewport.MoveToY(visualViewport.Y());
-     } else if (visualViewport.YMost() < mViewport.YMost()) {
+        aLayoutViewport.MoveToY(aVisualViewport.Y());
+     } else if (aVisualViewport.YMost() < aLayoutViewport.YMost()) {
         // layout viewport moves up
-        mViewport.MoveByY(visualViewport.YMost() - mViewport.YMost());
+        aLayoutViewport.MoveByY(aVisualViewport.YMost() - aLayoutViewport.YMost());
      }
    } else {
 
-     if (visualViewport.X() < mViewport.X()) {
-        mViewport.MoveToX(visualViewport.X());
-     } else if (mViewport.XMost() < visualViewport.XMost()) {
-        mViewport.MoveByX(visualViewport.XMost() - mViewport.XMost());
+     if (aVisualViewport.X() < aLayoutViewport.X()) {
+        aLayoutViewport.MoveToX(aVisualViewport.X());
+     } else if (aLayoutViewport.XMost() < aVisualViewport.XMost()) {
+        aLayoutViewport.MoveByX(aVisualViewport.XMost() - aLayoutViewport.XMost());
      }
-     if (visualViewport.Y() < mViewport.Y()) {
-        mViewport.MoveToY(visualViewport.Y());
-     } else if (mViewport.YMost() < visualViewport.YMost()) {
-        mViewport.MoveByY(visualViewport.YMost() - mViewport.YMost());
+     if (aVisualViewport.Y() < aLayoutViewport.Y()) {
+        aLayoutViewport.MoveToY(aVisualViewport.Y());
+     } else if (aLayoutViewport.YMost() < aVisualViewport.YMost()) {
+        aLayoutViewport.MoveByY(aVisualViewport.YMost() - aLayoutViewport.YMost());
      }
    }
 }
 
+
 void
 ScrollMetadata::SetUsesContainerScrolling(bool aValue) {
   mUsesContainerScrolling = aValue;
 }
 
 static OverscrollBehavior
 ToOverscrollBehavior(StyleOverscrollBehavior aBehavior)
 {
--- a/gfx/layers/FrameMetrics.h
+++ b/gfx/layers/FrameMetrics.h
@@ -533,16 +533,26 @@ public:
 
   // Determine if the visual viewport is outside of the layout viewport and
   // adjust the x,y-offset in mViewport accordingly. This is necessary to
   // allow APZ to async-scroll the layout viewport.
   //
   // This is a no-op if mIsRootContent is false.
   void RecalculateViewportOffset();
 
+  // Helper function for RecalculateViewportOffset(). Exposed so that
+  // APZC can perform the operation on other copies of the layout
+  // and visual viewport rects (e.g. the "effective" ones used to implement
+  // the frame delay).
+  // Modifies |aLayoutViewport| to continue enclosing |aVisualViewport|
+  // if possible.
+  static void KeepLayoutViewportEnclosingVisualViewport(
+      const CSSRect& aVisualViewport,
+      CSSRect& aLayoutViewport);
+
 private:
   // A unique ID assigned to each scrollable frame.
   ViewID mScrollId;
 
   // The pres-shell resolution that has been induced on the document containing
   // this scroll frame as a result of zooming this scroll frame (whether via
   // user action, or choosing an initial zoom level on page load). This can
   // only be different from 1.0 for frames that are zoomable, which currently
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -3343,16 +3343,24 @@ void AsyncPanZoomController::AdjustScrol
   CSSRect scrollRange = Metrics().CalculateScrollRange();
   // Apply shift to Metrics().mScrollOffset.
   SetScrollOffset(scrollRange.ClampPoint(
       Metrics().GetScrollOffset() + adjustment));
   // Apply shift to mCompositedScrollOffset, since the dynamic toolbar expects
   // the shift to take effect right away, without the usual frame delay.
   mCompositedScrollOffset = scrollRange.ClampPoint(
       mCompositedScrollOffset + adjustment);
+  // For a similar reason, apply the shift to mCompositedLayoutViewport.
+  // mCompositedLayoutViewport also needs to immediately pick up any new
+  // size from Metrics().GetViewport() to make sure it reflects any height
+  // change due to dynamic toolbar movement.
+  mCompositedLayoutViewport.SizeTo(Metrics().GetViewport().Size());
+  FrameMetrics::KeepLayoutViewportEnclosingVisualViewport(
+      CSSRect(mCompositedScrollOffset, Metrics().CalculateCompositedSizeInCssPixels()),
+      mCompositedLayoutViewport);
   RequestContentRepaint();
   UpdateSharedCompositorFrameMetrics();
 }
 
 void AsyncPanZoomController::SetScrollOffset(const CSSPoint& aOffset) {
   Metrics().SetScrollOffset(aOffset);
   Metrics().RecalculateViewportOffset();
 }