Bug 1040226 - Avoid getting stuck after overscroll is handed off to an APZC later in the handoff chain. r=kats

This commit is contained in:
Botond Ballo 2014-07-21 14:36:37 -04:00
parent 6cad61179f
commit 623142d1e3
4 changed files with 56 additions and 4 deletions

View File

@ -907,6 +907,23 @@ APZCTreeManager::CancelAnimationsForOverscrollHandoffChain()
return mOverscrollHandoffChain.length() > 0;
}
void
APZCTreeManager::SnapBackOverscrolledApzc(AsyncPanZoomController* aApzc)
{
// This is called when a fling is winding down, so there is no overscroll
// handoff chain already built, so build it now.
BuildOverscrollHandoffChain(aApzc);
MonitorAutoLock lock(mTreeLock);
// Exactly one APZC along the hand-off chain can be overscrolled.
// Find it, and start a snap-back animation for it.
for (uint32_t i = 0; i < mOverscrollHandoffChain.length(); ++i) {
if (mOverscrollHandoffChain[i]->SnapBackIfOverscrolled()) {
break;
}
}
mOverscrollHandoffChain.clear();
}
bool
APZCTreeManager::CanBePanned(AsyncPanZoomController* aApzc)
{

View File

@ -294,6 +294,7 @@ public:
bool FlushRepaintsForOverscrollHandoffChain();
bool CancelAnimationsForOverscrollHandoffChain();
void SnapBackOverscrolledApzc(AsyncPanZoomController* aStart);
/**
* Determine whether |aApzc|, or any APZC along its overscroll handoff chain,

View File

@ -496,10 +496,10 @@ public:
// If we shouldn't continue the fling, let's just stop and repaint.
if (!shouldContinueFlingX && !shouldContinueFlingY) {
APZC_LOG("%p ending fling animation. overscrolled=%d\n", &mApzc, mApzc.IsOverscrolled());
// If we are in overscroll, schedule the snap-back animation that relieves it.
if (mApzc.IsOverscrolled()) {
mDeferredTasks.append(NewRunnableMethod(&mApzc, &AsyncPanZoomController::StartSnapBack));
}
// This APZC or an APZC further down the handoff chain may be be overscrolled.
// Start a snap-back animation on the overscrolled APZC.
mDeferredTasks.append(NewRunnableMethod(&mApzc,
&AsyncPanZoomController::CallSnapBackOverscrolledApzc));
return false;
}
@ -654,6 +654,11 @@ public:
OverscrollSnapBackAnimation(AsyncPanZoomController& aApzc)
: mApzc(aApzc)
{
// Make sure the initial velocity is zero. This is normally the case
// since we've just stopped a fling, but in some corner cases involving
// handoff it could not be.
mApzc.mX.SetVelocity(0);
mApzc.mY.SetVelocity(0);
}
virtual bool Sample(FrameMetrics& aFrameMetrics,
@ -1767,6 +1772,13 @@ bool AsyncPanZoomController::CallDispatchScroll(const ScreenPoint& aStartPoint,
aOverscrollHandoffChainIndex);
}
void AsyncPanZoomController::CallSnapBackOverscrolledApzc() {
APZCTreeManager* treeManagerLocal = mTreeManager;
if (treeManagerLocal) {
treeManagerLocal->SnapBackOverscrolledApzc(this);
}
}
void AsyncPanZoomController::TrackTouch(const MultiTouchInput& aEvent) {
ScreenIntPoint prevTouchPoint(mX.GetPos(), mY.GetPos());
ScreenIntPoint touchPoint = GetFirstTouchScreenPoint(aEvent);
@ -1957,6 +1969,16 @@ void AsyncPanZoomController::FlushRepaintForOverscrollHandoff() {
UpdateSharedCompositorFrameMetrics();
}
bool AsyncPanZoomController::SnapBackIfOverscrolled() {
ReentrantMonitorAutoEnter lock(mMonitor);
if (IsOverscrolled()) {
APZC_LOG("%p is overscrolled, starting snap-back\n", this);
StartSnapBack();
return true;
}
return false;
}
bool AsyncPanZoomController::IsPannable() const {
ReentrantMonitorAutoEnter lock(mMonitor);
return mX.CanScroll() || mY.CanScroll();

View File

@ -903,6 +903,12 @@ public:
void FlushRepaintForOverscrollHandoff();
/**
* If overscrolled, start a snap-back animation and return true.
* Otherwise return false.
*/
bool SnapBackIfOverscrolled();
private:
FrameMetrics::ViewID mScrollParentId;
@ -914,6 +920,12 @@ private:
bool CallDispatchScroll(const ScreenPoint& aStartPoint, const ScreenPoint& aEndPoint,
uint32_t aOverscrollHandoffChainIndex);
/**
* A similar helper function for calling
* APZCTreeManager::SnapBackOverscrolledApzc().
*/
void CallSnapBackOverscrolledApzc();
/**
* Try to overscroll by 'aOverscroll'.
* If we are pannable, 'aOverscroll' is added to any existing overscroll,