Bug 1033398 - Ensure we request composites while overscroll is being reduced by touch input. r=drs
authorKartikaya Gupta <kgupta@mozilla.com>
Thu, 03 Jul 2014 18:26:04 -0400
changeset 192271 60051d7558c4d479f2bcc2c87446377802e31194
parent 192270 954509139d295df97206f867d1e8f4f1588c048d
child 192272 a9ffbd31b81c62fcf9debf6ca807bc9d7004ddc3
push id27078
push userryanvm@gmail.com
push dateFri, 04 Jul 2014 03:04:00 +0000
treeherdermozilla-central@39bf1eaa9190 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdrs
bugs1033398
milestone33.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 1033398 - Ensure we request composites while overscroll is being reduced by touch input. r=drs
gfx/layers/apz/src/AsyncPanZoomController.cpp
gfx/layers/apz/src/Axis.cpp
gfx/layers/apz/src/Axis.h
--- a/gfx/layers/apz/src/AsyncPanZoomController.cpp
+++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp
@@ -520,21 +520,27 @@ public:
     // vector classes.
     ScreenPoint velocity(mApzc.mX.GetVelocity(), mApzc.mY.GetVelocity());
 
     ScreenPoint offset = velocity * aDelta.ToMilliseconds();
 
     // Inversely scale the offset by the resolution (when you're zoomed further in,
     // the same swipe should move you a shorter distance).
     CSSPoint cssOffset = offset / aFrameMetrics.GetZoom();
+
+    // Ordinarily we might need to do a ScheduleComposite if either of
+    // the following AdjustDisplacement calls returns true, but this
+    // is already running as part of a FlingAnimation, so we'll be compositing
+    // per frame of animation anyway.
     CSSPoint overscroll;
-    aFrameMetrics.ScrollBy(CSSPoint(
-      mApzc.mX.AdjustDisplacement(cssOffset.x, overscroll.x),
-      mApzc.mY.AdjustDisplacement(cssOffset.y, overscroll.y)
-    ));
+    CSSPoint adjustedOffset;
+    mApzc.mX.AdjustDisplacement(cssOffset.x, adjustedOffset.x, overscroll.x);
+    mApzc.mY.AdjustDisplacement(cssOffset.y, adjustedOffset.y, overscroll.y);
+
+    aFrameMetrics.ScrollBy(adjustedOffset);
 
     // The fling may have caused us to reach the end of our scroll range.
     if (!IsZero(overscroll)) {
       if (mAllowOverscroll) {
         // If this is a fling that allows overscroll, then go into overscroll.
 
         mApzc.OverscrollBy(overscroll);
 
@@ -1608,24 +1614,27 @@ bool AsyncPanZoomController::AttemptScro
     ReentrantMonitorAutoEnter lock(mMonitor);
 
     CSSToScreenScale zoom = mFrameMetrics.GetZoom();
 
     // Inversely scale the offset by the resolution (when you're zoomed further in,
     // the same swipe should move you a shorter distance).
     CSSPoint cssDisplacement = displacement / zoom;
 
-    CSSPoint allowedDisplacement(mX.AdjustDisplacement(cssDisplacement.x,
-                                                       cssOverscroll.x),
-                                 mY.AdjustDisplacement(cssDisplacement.y,
-                                                       cssOverscroll.y));
+    CSSPoint adjustedDisplacement;
+    bool xChanged = mX.AdjustDisplacement(cssDisplacement.x, adjustedDisplacement.x, cssOverscroll.x);
+    bool yChanged = mY.AdjustDisplacement(cssDisplacement.y, adjustedDisplacement.y, cssOverscroll.y);
+    if (xChanged || yChanged) {
+      ScheduleComposite();
+    }
+
     overscroll = cssOverscroll * zoom;
 
-    if (!IsZero(allowedDisplacement)) {
-      ScrollBy(allowedDisplacement);
+    if (!IsZero(adjustedDisplacement)) {
+      ScrollBy(adjustedDisplacement);
       ScheduleCompositeAndMaybeRepaint();
       UpdateSharedCompositorFrameMetrics();
     }
   }
 
   // If we consumed the entire displacement as a normal scroll, great.
   if (IsZero(overscroll)) {
     return true;
--- a/gfx/layers/apz/src/Axis.cpp
+++ b/gfx/layers/apz/src/Axis.cpp
@@ -57,45 +57,49 @@ void Axis::UpdateWithTouchAtDevicePoint(
 
 void Axis::StartTouch(int32_t aPos, uint32_t aTimestampMs) {
   mStartPos = aPos;
   mPos = aPos;
   mPosTimeMs = aTimestampMs;
   mAxisLocked = false;
 }
 
-float Axis::AdjustDisplacement(float aDisplacement, float& aOverscrollAmountOut) {
+bool Axis::AdjustDisplacement(float aDisplacement,
+                              float& aDisplacementOut,
+                              float& aOverscrollAmountOut)
+{
   if (mAxisLocked) {
     aOverscrollAmountOut = 0;
-    return 0;
+    aDisplacementOut = 0;
+    return false;
   }
 
   float displacement = aDisplacement;
 
   // First consume any overscroll in the opposite direction along this axis.
+  float consumedOverscroll = 0;
   if (mOverscroll > 0 && aDisplacement < 0) {
-    float consumedOverscroll = std::min(mOverscroll, -aDisplacement);
-    mOverscroll -= consumedOverscroll;
-    displacement += consumedOverscroll;
+    consumedOverscroll = std::min(mOverscroll, -aDisplacement);
   } else if (mOverscroll < 0 && aDisplacement > 0) {
-    float consumedOverscroll = std::min(-mOverscroll, aDisplacement);
-    mOverscroll += consumedOverscroll;
-    displacement -= consumedOverscroll;
+    consumedOverscroll = 0 - std::min(-mOverscroll, aDisplacement);
   }
+  mOverscroll -= consumedOverscroll;
+  displacement += consumedOverscroll;
 
   // Split the requested displacement into an allowed displacement that does
   // not overscroll, and an overscroll amount.
   if (DisplacementWillOverscroll(displacement) != OVERSCROLL_NONE) {
     // No need to have a velocity along this axis anymore; it won't take us
     // anywhere, so we're just spinning needlessly.
     mVelocity = 0.0f;
     aOverscrollAmountOut = DisplacementWillOverscrollAmount(displacement);
     displacement -= aOverscrollAmountOut;
   }
-  return displacement;
+  aDisplacementOut = displacement;
+  return fabsf(consumedOverscroll) > EPSILON;
 }
 
 float Axis::ApplyResistance(float aRequestedOverscroll) const {
   // 'resistanceFactor' is a value between 0 and 1, which:
   //   - tends to 1 as the existing overscroll tends to 0
   //   - tends to 0 as the existing overscroll tends to the composition length
   // The actual overscroll is the requested overscroll multiplied by this
   // factor; this should prevent overscrolling by more than the composition
--- a/gfx/layers/apz/src/Axis.h
+++ b/gfx/layers/apz/src/Axis.h
@@ -78,19 +78,23 @@ public:
   void CancelTouch();
 
   /**
    * Takes a requested displacement to the position of this axis, and adjusts it
    * to account for overscroll (which might decrease the displacement; this is
    * to prevent the viewport from overscrolling the page rect), and axis locking
    * (which might prevent any displacement from happening). If overscroll
    * ocurred, its amount is written to |aOverscrollAmountOut|.
-   * The adjusted displacement is returned.
+   * The |aDisplacementOut| parameter is set to the adjusted
+   * displacement, and the function returns true iff internal overscroll amounts
+   * were changed.
    */
-  float AdjustDisplacement(float aDisplacement, float& aOverscrollAmountOut);
+  bool AdjustDisplacement(float aDisplacement,
+                          float& aDisplacementOut,
+                          float& aOverscrollAmountOut);
 
   /**
    * Overscrolls this axis by the requested amount in the requested direction.
    * The axis must be at the end of its scroll range in this direction.
    */
   void OverscrollBy(float aOverscroll);
 
   /**