Bug 1292034 - Update the StackScroller with the elapsed time from the previous fling before starting a new one, so that it doesn't use a stale velocity for flywheel. r?rbarker
MozReview-Commit-ID: GPg1ZQ6SCMm
--- a/gfx/layers/apz/src/AndroidAPZ.cpp
+++ b/gfx/layers/apz/src/AndroidAPZ.cpp
@@ -75,18 +75,19 @@ AndroidFlingAnimation::AndroidFlingAnima
: mApzc(aApzc)
, mOverscrollHandoffChain(aOverscrollHandoffChain)
, mScrolledApzc(aScrolledApzc)
, mSentBounceX(false)
, mSentBounceY(false)
, mFlingDuration(0)
{
MOZ_ASSERT(mOverscrollHandoffChain);
- MOZ_ASSERT(aPlatformSpecificState->AsAndroidSpecificState());
- mOverScroller = aPlatformSpecificState->AsAndroidSpecificState()->mOverScroller;
+ AndroidSpecificState* state = aPlatformSpecificState->AsAndroidSpecificState();
+ MOZ_ASSERT(state);
+ mOverScroller = state->mOverScroller;
MOZ_ASSERT(mOverScroller);
// Drop any velocity on axes where we don't have room to scroll anyways
// (in this APZC, or an APZC further in the handoff chain).
// This ensures that we don't take the 'overscroll' path in Sample()
// on account of one axis which can't scroll having a velocity.
if (!mOverscrollHandoffChain->CanScrollInDirection(&mApzc, Layer::HORIZONTAL)) {
ReentrantMonitorAutoEnter lock(mApzc.mMonitor);
@@ -113,22 +114,30 @@ AndroidFlingAnimation::AndroidFlingAnima
velocity = mFlingDirection * sMaxFlingSpeed;
}
}
mPreviousVelocity = velocity;
int32_t originX = ClampStart(mStartOffset.x, scrollRangeStartX, scrollRangeEndX);
int32_t originY = ClampStart(mStartOffset.y, scrollRangeStartY, scrollRangeEndY);
+ if (!state->mLastFling.IsNull()) {
+ // If we had a fling going previously, we should update the timestamp on
+ // it because otherwise it may have a stale velocity
+ TimeDuration flingDuration = TimeStamp::Now() - state->mLastFling;
+ bool unused = false;
+ mOverScroller->ComputeScrollOffset(flingDuration.ToMilliseconds(), &unused);
+ }
mOverScroller->Fling(originX, originY,
// Android needs the velocity in pixels per second and it is in pixels per ms.
(int32_t)(velocity.x * 1000.0f), (int32_t)(velocity.y * 1000.0f),
(int32_t)floor(scrollRangeStartX), (int32_t)ceil(scrollRangeEndX),
(int32_t)floor(scrollRangeStartY), (int32_t)ceil(scrollRangeEndY),
0, 0, 0);
+ state->mLastFling = TimeStamp::Now();
}
/**
* Advances a fling by an interpolated amount based on the Android OverScroller.
* This should be called whenever sampling the content transform for this
* frame. Returns true if the fling animation should be advanced by one frame,
* or false if there is no fling or the fling has ended.
*/
--- a/gfx/layers/apz/src/AndroidAPZ.h
+++ b/gfx/layers/apz/src/AndroidAPZ.h
@@ -18,16 +18,17 @@ class AndroidSpecificState : public Plat
public:
AndroidSpecificState();
virtual AndroidSpecificState* AsAndroidSpecificState() override {
return this;
}
java::StackScroller::GlobalRef mOverScroller;
+ TimeStamp mLastFling;
};
class AndroidFlingAnimation: public AsyncPanZoomAnimation {
public:
AndroidFlingAnimation(AsyncPanZoomController& aApzc,
PlatformSpecificStateBase* aPlatformSpecificState,
const RefPtr<const OverscrollHandoffChain>& aOverscrollHandoffChain,
bool aFlingIsHandoff /* ignored */,