Bug 1042103 - Allow overscroll to be retained between input blocks. r=botond

This commit is contained in:
Chris Lord 2015-01-20 00:04:07 +00:00
parent 4e9e7de4ac
commit b8d9440f3e
10 changed files with 52 additions and 13 deletions

View File

@ -1497,7 +1497,7 @@ APZCTreeManager::GetScreenToApzcTransform(const AsyncPanZoomController *aApzc) c
// ancestorUntransform is updated to RC.Inverse() * QC.Inverse() when parent == P
ancestorUntransform = parent->GetAncestorTransform().Inverse();
// asyncUntransform is updated to PA.Inverse() when parent == P
Matrix4x4 asyncUntransform = Matrix4x4(parent->GetCurrentAsyncTransform()).Inverse();
Matrix4x4 asyncUntransform = parent->GetCurrentAsyncTransformWithOverscroll().Inverse();
// untransformSinceLastApzc is RC.Inverse() * QC.Inverse() * PA.Inverse()
Matrix4x4 untransformSinceLastApzc = ancestorUntransform * asyncUntransform;
@ -1529,7 +1529,7 @@ APZCTreeManager::GetApzcToGeckoTransform(const AsyncPanZoomController *aApzc) co
// leftmost matrix in a multiplication is applied first.
// asyncUntransform is LA.Inverse()
Matrix4x4 asyncUntransform = Matrix4x4(aApzc->GetCurrentAsyncTransform()).Inverse();
Matrix4x4 asyncUntransform = aApzc->GetCurrentAsyncTransformWithOverscroll().Inverse();
// aTransformToGeckoOut is initialized to LA.Inverse() * LD * MC * NC * OC * PC
result = asyncUntransform * aApzc->GetTransformToLastDispatchedPaint() * aApzc->GetAncestorTransform();

View File

@ -16,6 +16,11 @@ enum HitTestResult {
HitDispatchToContentRegion,
};
enum CancelAnimationFlags : uint32_t {
Default = 0, /* Cancel all animations */
ExcludeOverscroll = 1 /* Don't clear overscroll */
};
}
}

View File

@ -1147,7 +1147,7 @@ nsEventStatus AsyncPanZoomController::OnTouchStart(const MultiTouchInput& aEvent
case ANIMATING_ZOOM:
case SMOOTH_SCROLL:
case OVERSCROLL_ANIMATION:
CurrentTouchBlock()->GetOverscrollHandoffChain()->CancelAnimations();
CurrentTouchBlock()->GetOverscrollHandoffChain()->CancelAnimations(ExcludeOverscroll);
// Fall through.
case NOTHING: {
mX.StartTouch(point.x, aEvent.mTime);
@ -1270,7 +1270,11 @@ nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent)
// that were not big enough to trigger scrolling. Clear that out.
mX.SetVelocity(0);
mY.SetVelocity(0);
SetState(NOTHING);
// It's possible we may be overscrolled if the user tapped during a
// previous overscroll pan. Make sure to snap back in this situation.
if (!SnapBackIfOverscrolled()) {
SetState(NOTHING);
}
return nsEventStatus_eIgnore;
case PANNING:
@ -2165,7 +2169,7 @@ void AsyncPanZoomController::StartAnimation(AsyncPanZoomAnimation* aAnimation)
ScheduleComposite();
}
void AsyncPanZoomController::CancelAnimation() {
void AsyncPanZoomController::CancelAnimation(CancelAnimationFlags aFlags) {
ReentrantMonitorAutoEnter lock(mMonitor);
APZC_LOG("%p running CancelAnimation in state %d\n", this, mState);
SetState(NOTHING);
@ -2177,7 +2181,7 @@ void AsyncPanZoomController::CancelAnimation() {
// Setting the state to nothing and cancelling the animation can
// preempt normal mechanisms for relieving overscroll, so we need to clear
// overscroll here.
if (mX.IsOverscrolled() || mY.IsOverscrolled()) {
if (!(aFlags & ExcludeOverscroll) && IsOverscrolled()) {
ClearOverscroll();
RequestContentRepaint();
ScheduleComposite();
@ -2654,6 +2658,10 @@ ViewTransform AsyncPanZoomController::GetCurrentAsyncTransform() const {
return ViewTransform(mFrameMetrics.GetAsyncZoom(), -translation);
}
Matrix4x4 AsyncPanZoomController::GetCurrentAsyncTransformWithOverscroll() const {
return Matrix4x4(GetCurrentAsyncTransform()) * GetOverscrollTransform();
}
Matrix4x4 AsyncPanZoomController::GetTransformToLastDispatchedPaint() const {
ReentrantMonitorAutoEnter lock(mMonitor);

View File

@ -20,6 +20,7 @@
#include "InputData.h"
#include "Axis.h"
#include "InputQueue.h"
#include "APZUtils.h"
#include "LayersTypes.h"
#include "TaskThrottler.h"
#include "mozilla/gfx/Matrix.h"
@ -217,6 +218,12 @@ public:
*/
ViewTransform GetCurrentAsyncTransform() const;
/**
* Returns the same transform as GetCurrentAsyncTransform(), but includes
* any transform due to axis over-scroll.
*/
Matrix4x4 GetCurrentAsyncTransformWithOverscroll() const;
/**
* Returns the transform to take something from the coordinate space of the
* last thing we know gecko painted, to the coordinate space of the last thing
@ -285,8 +292,10 @@ public:
/**
* Cancels any currently running animation.
* aFlags is a bit-field to provide specifics of how to cancel the animation.
* See CancelAnimationFlags.
*/
void CancelAnimation();
void CancelAnimation(CancelAnimationFlags aFlags = Default);
/**
* Clear any overscroll on this APZC.

View File

@ -126,6 +126,8 @@ bool Axis::AdjustDisplacement(ParentLayerCoord aDisplacement,
return false;
}
StopSamplingOverscrollAnimation();
ParentLayerCoord displacement = aDisplacement;
// First consume any overscroll in the opposite direction along this axis.
@ -160,12 +162,13 @@ ParentLayerCoord Axis::ApplyResistance(ParentLayerCoord aRequestedOverscroll) co
// The actual overscroll is the requested overscroll multiplied by this
// factor; this should prevent overscrolling by more than the composition
// length.
float resistanceFactor = 1 - fabsf(mOverscroll) / GetCompositionLength();
float resistanceFactor = 1 - fabsf(GetOverscroll()) / GetCompositionLength();
return resistanceFactor < 0 ? ParentLayerCoord(0) : aRequestedOverscroll * resistanceFactor;
}
void Axis::OverscrollBy(ParentLayerCoord aOverscroll) {
MOZ_ASSERT(CanScroll());
StopSamplingOverscrollAnimation();
aOverscroll = ApplyResistance(aOverscroll);
if (aOverscroll > 0) {
#ifdef DEBUG
@ -200,6 +203,12 @@ ParentLayerCoord Axis::GetOverscroll() const {
return result;
}
void Axis::StopSamplingOverscrollAnimation() {
ParentLayerCoord overscroll = GetOverscroll();
ClearOverscroll();
mOverscroll = overscroll;
}
void Axis::StepOverscrollAnimation(double aStepDurationMilliseconds) {
// Apply spring physics to the overscroll as time goes on.
// Note: this method of sampling isn't perfectly smooth, as it assumes

View File

@ -251,6 +251,10 @@ protected:
// actual overscroll amount.
ParentLayerCoord ApplyResistance(ParentLayerCoord aOverscroll) const;
// Helper function to disable overscroll transformations triggered by
// SampleOverscrollAnimation().
void StopSamplingOverscrollAnimation();
// Helper function for SampleOverscrollAnimation().
void StepOverscrollAnimation(double aStepDurationMilliseconds);

View File

@ -174,7 +174,7 @@ HitTestingTreeNode::Untransform(const ParentLayerPoint& aPoint) const
// convert into Layer coordinate space
gfx::Matrix4x4 localTransform = mTransform;
if (mApzc) {
localTransform = localTransform * gfx::Matrix4x4(mApzc->GetCurrentAsyncTransform());
localTransform = localTransform * mApzc->GetCurrentAsyncTransformWithOverscroll();
}
gfx::Point4D point = localTransform.Inverse().ProjectPoint(aPoint.ToUnknownPoint());
return point.HasPositiveWCoord()

View File

@ -186,7 +186,7 @@ InputQueue::CancelAnimationsForNewBlock(CancelableBlockState* aBlock)
INPQ_LOG("block %p tagged as fast-motion\n", touch);
}
}
aBlock->GetOverscrollHandoffChain()->CancelAnimations();
aBlock->GetOverscrollHandoffChain()->CancelAnimations(ExcludeOverscroll);
}
}

View File

@ -88,9 +88,12 @@ OverscrollHandoffChain::FlushRepaints() const
}
void
OverscrollHandoffChain::CancelAnimations() const
OverscrollHandoffChain::CancelAnimations(CancelAnimationFlags aFlags) const
{
ForEachApzc(&AsyncPanZoomController::CancelAnimation);
MOZ_ASSERT(Length() > 0);
for (uint32_t i = 0; i < Length(); ++i) {
mChain[i]->CancelAnimation(aFlags);
}
}
void

View File

@ -11,6 +11,7 @@
#include "nsAutoPtr.h"
#include "nsISupportsImpl.h" // for NS_INLINE_DECL_REFCOUNTING
#include "Units.h" // for ScreenPoint
#include "APZUtils.h" // for CancelAnimationFlags
namespace mozilla {
namespace layers {
@ -93,7 +94,7 @@ public:
void FlushRepaints() const;
// Cancel animations all the way up the chain.
void CancelAnimations() const;
void CancelAnimations(CancelAnimationFlags aFlags = Default) const;
// Clear overscroll all the way up the chain.
void ClearOverscroll() const;