Bug 1230552 - Extend the immediate scroll handoff pref to apply to flings. r=kats

--HG--
extra : commitid : A4UZJ8vLfjW
extra : rebase_source : f46922f1b13ec8fded72e5eb09045a8fe6e2dc03
This commit is contained in:
Botond Ballo 2015-12-12 14:31:25 -05:00
Родитель ab1b789f18
Коммит e8098f6ff2
5 изменённых файлов: 62 добавлений и 8 удалений

Просмотреть файл

@ -1417,6 +1417,14 @@ void
APZCTreeManager::DispatchFling(AsyncPanZoomController* aPrev,
FlingHandoffState& aHandoffState)
{
// If immediate handoff is disallowed, do not allow handoff beyond the
// single APZC that's scrolled by the input block that triggered this fling.
if (aHandoffState.mIsHandoff &&
!gfxPrefs::APZAllowImmediateHandoff() &&
aHandoffState.mScrolledApzc == aPrev) {
return;
}
const OverscrollHandoffChain* chain = aHandoffState.mChain;
RefPtr<AsyncPanZoomController> current;
uint32_t overscrollHandoffChainLength = chain->Length();

Просмотреть файл

@ -444,10 +444,12 @@ class FlingAnimation: public AsyncPanZoomAnimation {
public:
FlingAnimation(AsyncPanZoomController& aApzc,
const RefPtr<const OverscrollHandoffChain>& aOverscrollHandoffChain,
bool aApplyAcceleration)
bool aApplyAcceleration,
const RefPtr<const AsyncPanZoomController>& aScrolledApzc)
: AsyncPanZoomAnimation(TimeDuration::FromMilliseconds(gfxPrefs::APZFlingRepaintInterval()))
, mApzc(aApzc)
, mOverscrollHandoffChain(aOverscrollHandoffChain)
, mScrolledApzc(aScrolledApzc)
{
MOZ_ASSERT(mOverscrollHandoffChain);
TimeStamp now = aApzc.GetFrameTime();
@ -572,7 +574,8 @@ public:
mDeferredTasks.append(NewRunnableMethod(&mApzc,
&AsyncPanZoomController::HandleFlingOverscroll,
velocity,
mOverscrollHandoffChain));
mOverscrollHandoffChain,
mScrolledApzc));
// If there is a remaining velocity on this APZC, continue this fling
// as well. (This fling and the handed-off fling will run concurrently.)
@ -600,6 +603,7 @@ private:
AsyncPanZoomController& mApzc;
RefPtr<const OverscrollHandoffChain> mOverscrollHandoffChain;
RefPtr<const AsyncPanZoomController> mScrolledApzc;
};
class ZoomAnimation: public AsyncPanZoomAnimation {
@ -1375,7 +1379,8 @@ nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent)
if (APZCTreeManager* treeManagerLocal = GetApzcTreeManager()) {
FlingHandoffState handoffState{flingVelocity,
CurrentTouchBlock()->GetOverscrollHandoffChain(),
false /* not handoff */};
false /* not handoff */,
CurrentTouchBlock()->GetScrolledApzc()};
treeManagerLocal->DispatchFling(this, handoffState);
}
return nsEventStatus_eConsumeNoDefault;
@ -2428,7 +2433,8 @@ void AsyncPanZoomController::AcceptFling(FlingHandoffState& aHandoffState) {
SetState(FLING);
FlingAnimation *fling = new FlingAnimation(*this,
aHandoffState.mChain,
!aHandoffState.mIsHandoff); // only apply acceleration if this is an initial fling
!aHandoffState.mIsHandoff, // only apply acceleration if this is an initial fling
aHandoffState.mScrolledApzc);
float friction = gfxPrefs::APZFlingFriction();
ParentLayerPoint velocity(mX.GetVelocity(), mY.GetVelocity());
@ -2477,12 +2483,14 @@ bool AsyncPanZoomController::AttemptFling(FlingHandoffState& aHandoffState) {
}
void AsyncPanZoomController::HandleFlingOverscroll(const ParentLayerPoint& aVelocity,
const RefPtr<const OverscrollHandoffChain>& aOverscrollHandoffChain) {
const RefPtr<const OverscrollHandoffChain>& aOverscrollHandoffChain,
const RefPtr<const AsyncPanZoomController>& aScrolledApzc) {
APZCTreeManager* treeManagerLocal = GetApzcTreeManager();
if (treeManagerLocal) {
FlingHandoffState handoffState{aVelocity,
aOverscrollHandoffChain,
true /* handoff */};
true /* handoff */,
aScrolledApzc};
treeManagerLocal->DispatchFling(this, handoffState);
if (!IsZero(handoffState.mVelocity) && IsPannable() && gfxPrefs::APZOverscrollEnabled()) {
StartOverscrollAnimation(handoffState.mVelocity);
@ -2493,7 +2501,7 @@ void AsyncPanZoomController::HandleFlingOverscroll(const ParentLayerPoint& aVelo
void AsyncPanZoomController::HandleSmoothScrollOverscroll(const ParentLayerPoint& aVelocity) {
// We must call BuildOverscrollHandoffChain from this deferred callback
// function in order to avoid a deadlock when acquiring the tree lock.
HandleFlingOverscroll(aVelocity, BuildOverscrollHandoffChain());
HandleFlingOverscroll(aVelocity, BuildOverscrollHandoffChain(), nullptr);
}
void AsyncPanZoomController::StartSmoothScroll(ScrollSource aSource) {

Просмотреть файл

@ -867,7 +867,8 @@ private:
// later in the handoff chain, or if there are no takers, continuing the
// fling and entering an overscrolled state.
void HandleFlingOverscroll(const ParentLayerPoint& aVelocity,
const RefPtr<const OverscrollHandoffChain>& aOverscrollHandoffChain);
const RefPtr<const OverscrollHandoffChain>& aOverscrollHandoffChain,
const RefPtr<const AsyncPanZoomController>& aScrolledApzc);
void HandleSmoothScrollOverscroll(const ParentLayerPoint& aVelocity);

Просмотреть файл

@ -143,6 +143,11 @@ struct FlingHandoffState {
// Whether handoff has happened by this point, or we're still process
// the original fling.
bool mIsHandoff;
// The single APZC that was scrolled by the pan that started this fling.
// The fling is only allowed to scroll this APZC, too.
// Used only if immediate scroll handoff is disallowed.
RefPtr<const AsyncPanZoomController> mScrolledApzc;
};
} // namespace layers

Просмотреть файл

@ -3114,6 +3114,38 @@ TEST_F(APZOverscrollHandoffTester, ImmediateHandoffDisallowed_Pan) {
EXPECT_EQ(10, parentApzc->GetFrameMetrics().GetScrollOffset().y);
}
TEST_F(APZOverscrollHandoffTester, ImmediateHandoffDisallowed_Fling) {
SCOPED_GFX_PREF(APZAllowImmediateHandoff, bool, false);
CreateOverscrollHandoffLayerTree1();
RefPtr<TestAsyncPanZoomController> parentApzc = ApzcOf(root);
RefPtr<TestAsyncPanZoomController> childApzc = ApzcOf(layers[1]);
// Pan on the child, enough to get very close to the end, so that the
// subsequent fling reaches the end and has leftover velocity to hand off.
Pan(childApzc, mcc, 60, 12);
// Allow the fling to run its course.
childApzc->AdvanceAnimationsUntilEnd();
parentApzc->AdvanceAnimationsUntilEnd();
// Verify that the parent has not scrolled.
EXPECT_EQ(50, childApzc->GetFrameMetrics().GetScrollOffset().y);
EXPECT_EQ(0, parentApzc->GetFrameMetrics().GetScrollOffset().y);
// Pan again on the child. This time, since the child was scrolled to
// its end when the gesture began, we expect the scroll to be handed off.
Pan(childApzc, mcc, 60, 50);
// Allow the fling to run its course. The fling should also be handed off.
childApzc->AdvanceAnimationsUntilEnd();
parentApzc->AdvanceAnimationsUntilEnd();
// Verify that the parent scrolled from the fling.
EXPECT_GT(parentApzc->GetFrameMetrics().GetScrollOffset().y, 10);
}
class APZEventRegionsTester : public APZCTreeManagerTester {
protected:
UniquePtr<ScopedLayerTreeRegistration> registration;