зеркало из https://github.com/mozilla/gecko-dev.git
Bug 907123 - Implement fling acceleration on multiple consecutive flings. r=botond
This commit is contained in:
Родитель
36cf99e744
Коммит
a52f3f95dd
|
@ -163,6 +163,20 @@ typedef GeckoContentController::APZStateChange APZStateChange;
|
|||
* generated displayport's size is beyond that of the scrollable rect on the
|
||||
* opposite axis.
|
||||
*
|
||||
* "apz.fling_accel_interval_ms"
|
||||
* The time in milliseconds that determines whether a second fling will be
|
||||
* treated as accelerated. If two flings are started within this interval,
|
||||
* the second one will be accelerated. Setting an interval of 0 means that
|
||||
* acceleration will be disabled.
|
||||
*
|
||||
* "apz.fling_accel_base_mult"
|
||||
* "apz.fling_accel_supplemental_mult"
|
||||
* When applying an acceleration on a fling, the new computed velocity is
|
||||
* (new_fling_velocity * base_mult) + (old_velocity * supplemental_mult).
|
||||
* The base_mult and supplemental_mult multiplier values are controlled by
|
||||
* these prefs. Note that "old_velocity" here is the initial velocity of the
|
||||
* previous fling _after_ acceleration was applied to it (if applicable).
|
||||
*
|
||||
* "apz.fling_friction"
|
||||
* Amount of friction applied during flings.
|
||||
*
|
||||
|
@ -330,10 +344,40 @@ GetFrameTime() {
|
|||
|
||||
class FlingAnimation: public AsyncPanZoomAnimation {
|
||||
public:
|
||||
FlingAnimation(AsyncPanZoomController& aApzc)
|
||||
FlingAnimation(AsyncPanZoomController& aApzc, bool aApplyAcceleration)
|
||||
: AsyncPanZoomAnimation(TimeDuration::FromMilliseconds(gfxPrefs::APZFlingRepaintInterval()))
|
||||
, mApzc(aApzc)
|
||||
{}
|
||||
{
|
||||
TimeStamp now = GetFrameTime();
|
||||
ScreenPoint velocity(mApzc.mX.GetVelocity(), mApzc.mY.GetVelocity());
|
||||
|
||||
// If the last fling was very recent and in the same direction as this one,
|
||||
// boost the velocity to be the sum of the two. Check separate axes separately
|
||||
// because we could have two vertical flings with small horizontal components
|
||||
// on the opposite side of zero, and we still want the y-fling to get accelerated.
|
||||
// Note that the acceleration code is only applied on the APZC that receives the
|
||||
// actual touch event; the accelerated velocities are then handed off using the
|
||||
// normal HandOffFling codepath.
|
||||
if (aApplyAcceleration && !mApzc.mLastFlingTime.IsNull()
|
||||
&& (now - mApzc.mLastFlingTime).ToMilliseconds() < gfxPrefs::APZFlingAccelInterval()) {
|
||||
if (SameDirection(velocity.x, mApzc.mLastFlingVelocity.x)) {
|
||||
velocity.x = Accelerate(velocity.x, mApzc.mLastFlingVelocity.x);
|
||||
APZC_LOG("%p Applying fling x-acceleration from %f to %f (delta %f)\n",
|
||||
&mApzc, mApzc.mX.GetVelocity(), velocity.x, mApzc.mLastFlingVelocity.x);
|
||||
mApzc.mX.SetVelocity(velocity.x);
|
||||
}
|
||||
if (SameDirection(velocity.y, mApzc.mLastFlingVelocity.y)) {
|
||||
velocity.y = Accelerate(velocity.y, mApzc.mLastFlingVelocity.y);
|
||||
APZC_LOG("%p Applying fling y-acceleration from %f to %f (delta %f)\n",
|
||||
&mApzc, mApzc.mY.GetVelocity(), velocity.y, mApzc.mLastFlingVelocity.y);
|
||||
mApzc.mY.SetVelocity(velocity.y);
|
||||
}
|
||||
}
|
||||
|
||||
mApzc.mLastFlingTime = now;
|
||||
mApzc.mLastFlingVelocity = velocity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Advances a fling by an interpolated amount based on the passed in |aDelta|.
|
||||
* This should be called whenever sampling the content transform for this
|
||||
|
@ -344,6 +388,19 @@ public:
|
|||
const TimeDuration& aDelta);
|
||||
|
||||
private:
|
||||
static bool SameDirection(float aVelocity1, float aVelocity2)
|
||||
{
|
||||
return (aVelocity1 == 0.0f)
|
||||
|| (aVelocity2 == 0.0f)
|
||||
|| (IsNegative(aVelocity1) == IsNegative(aVelocity2));
|
||||
}
|
||||
|
||||
static float Accelerate(float aBase, float aSupplemental)
|
||||
{
|
||||
return (aBase * gfxPrefs::APZFlingAccelBaseMultiplier())
|
||||
+ (aSupplemental * gfxPrefs::APZFlingAccelSupplementalMultiplier());
|
||||
}
|
||||
|
||||
AsyncPanZoomController& mApzc;
|
||||
};
|
||||
|
||||
|
@ -755,7 +812,7 @@ nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent)
|
|||
mX.EndTouch();
|
||||
mY.EndTouch();
|
||||
SetState(FLING);
|
||||
StartAnimation(new FlingAnimation(*this));
|
||||
StartAnimation(new FlingAnimation(*this, true));
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
|
||||
case PINCHING:
|
||||
|
@ -1183,7 +1240,7 @@ void AsyncPanZoomController::TakeOverFling(ScreenPoint aVelocity) {
|
|||
mX.SetVelocity(mX.GetVelocity() + aVelocity.x);
|
||||
mY.SetVelocity(mY.GetVelocity() + aVelocity.y);
|
||||
SetState(FLING);
|
||||
StartAnimation(new FlingAnimation(*this));
|
||||
StartAnimation(new FlingAnimation(*this, false));
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::CallDispatchScroll(const ScreenPoint& aStartPoint, const ScreenPoint& aEndPoint,
|
||||
|
|
|
@ -778,6 +778,10 @@ public:
|
|||
|
||||
private:
|
||||
friend class FlingAnimation;
|
||||
// The initial velocity of the most recent fling.
|
||||
ScreenPoint mLastFlingVelocity;
|
||||
// The time at which the most recent fling started.
|
||||
TimeStamp mLastFlingTime;
|
||||
|
||||
|
||||
/* ===================================================================
|
||||
|
|
|
@ -111,6 +111,9 @@ private:
|
|||
DECL_GFX_PREF(Live, "apz.content_response_timeout", APZContentResponseTimeout, int32_t, 300);
|
||||
DECL_GFX_PREF(Live, "apz.cross_slide.enabled", APZCrossSlideEnabled, bool, false);
|
||||
DECL_GFX_PREF(Live, "apz.enlarge_displayport_when_clipped", APZEnlargeDisplayPortWhenClipped, bool, false);
|
||||
DECL_GFX_PREF(Live, "apz.fling_accel_interval_ms", APZFlingAccelInterval, int32_t, 500);
|
||||
DECL_GFX_PREF(Live, "apz.fling_accel_base_mult", APZFlingAccelBaseMultiplier, float, 1.0f);
|
||||
DECL_GFX_PREF(Live, "apz.fling_accel_supplemental_mult", APZFlingAccelSupplementalMultiplier, float, 1.0f);
|
||||
DECL_GFX_PREF(Once, "apz.fling_friction", APZFlingFriction, float, 0.002f);
|
||||
DECL_GFX_PREF(Live, "apz.fling_repaint_interval", APZFlingRepaintInterval, int32_t, 75);
|
||||
DECL_GFX_PREF(Once, "apz.fling_stopped_threshold", APZFlingStoppedThreshold, float, 0.01f);
|
||||
|
|
Загрузка…
Ссылка в новой задаче