Bug 1285239 - Scrolling can randomly get interrupted and show overscroll effect. r=botond, a=gchang
authorRandall Barker <rbarker@mozilla.com>
Thu, 07 Jul 2016 20:05:59 -0700
changeset 339903 3366b3cde4918ef217a57293f1cc9bd9a6656bcb
parent 339902 ea115aa628abd21b879228258690b33bcb0ddde7
child 339904 0ad38f4e2b4d6bb798fdb13b1fa53cfc8aebe2c7
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbotond, gchang
bugs1285239
milestone49.0a2
Bug 1285239 - Scrolling can randomly get interrupted and show overscroll effect. r=botond, a=gchang
gfx/layers/apz/src/AndroidAPZ.cpp
--- a/gfx/layers/apz/src/AndroidAPZ.cpp
+++ b/gfx/layers/apz/src/AndroidAPZ.cpp
@@ -139,34 +139,38 @@ AndroidFlingAnimation::DoSample(FrameMet
   // OverScroller::GetCurrVelocity will sometimes return NaN. So need to externally
   // calculate current velocity and not rely on what the OverScroller calculates.
   // mOverScroller->GetCurrVelocity(&speed);
   int32_t currentX = 0;
   int32_t currentY = 0;
   mOverScroller->GetCurrX(&currentX);
   mOverScroller->GetCurrY(&currentY);
   ParentLayerPoint offset((float)currentX, (float)currentY);
+  ParentLayerPoint preCheckedOffset(offset);
 
   bool hitBoundX = CheckBounds(mApzc.mX, offset.x, mFlingDirection.x, &(offset.x));
   bool hitBoundY = CheckBounds(mApzc.mY, offset.y, mFlingDirection.y, &(offset.y));
 
   ParentLayerPoint velocity = mPreviousVelocity;
 
   // Sometimes the OverScroller fails to update the offset for a frame.
   // If the frame can still scroll we just use the velocity from the previous
   // frame. However, if the frame can no longer scroll in the direction
   // of the fling, then end the animation.
   if (offset != mPreviousOffset) {
     if (aDelta.ToMilliseconds() > 0) {
       velocity = (offset - mPreviousOffset) / (float)aDelta.ToMilliseconds();
       mPreviousVelocity = velocity;
     }
-  } else if (hitBoundX || hitBoundY) {
-    // We have reached the end of the scroll in one of the directions being scrolled and the offset has not
-    // changed so end animation.
+  } else if ((fabsf(offset.x - preCheckedOffset.x) > BOUNDS_EPSILON) || (fabsf(offset.y - preCheckedOffset.y) > BOUNDS_EPSILON)) {
+    // The page is no longer scrolling but the fling animation is still animating beyond the page bounds. If it goes
+    // beyond the BOUNDS_EPSILON then it has overflowed and will never stop. In that case, stop the fling animation.
+    shouldContinueFling = false;
+  } else if (hitBoundX && hitBoundY) {
+    // We can't scroll any farther along either axis.
     shouldContinueFling = false;
   }
 
   float speed = velocity.Length();
 
   // gfxPrefs::APZFlingStoppedThreshold is only used in tests.
   if (!shouldContinueFling || (speed < gfxPrefs::APZFlingStoppedThreshold())) {
     if (shouldContinueFling) {