Bug 1448439 - Expose some of the tunable parameters in AndroidFlingPhysics as prefs. r=kats

MozReview-Commit-ID: J4QRmMdGE0l

--HG--
extra : rebase_source : 9acdec2fff2f95057cf2fc4da9fc8e86de4912f0
This commit is contained in:
Botond Ballo 2018-04-20 18:55:08 -04:00
Родитель a7f61a775c
Коммит 67bc5921a7
4 изменённых файлов: 57 добавлений и 10 удалений

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

@ -31,21 +31,40 @@ static double ComputeDeceleration(float aFriction)
const float kDecelerationRate = 2.3582018f;
// Default friction constant in android.view.ViewConfiguration.
const float kFlingFriction = 0.015f;
static float GetFlingFriction()
{
return gfxPrefs::APZChromeFlingPhysicsFriction();
}
// Tension lines cross at (kInflexion, 1).
const float kInflexion = 0.35f;
// Tension lines cross at (GetInflexion(), 1).
static float GetInflexion()
{
// Clamp the inflexion to the range [0,1]. Values outside of this range
// do not make sense in the physics model, and for negative values the
// approximation used to compute the spline curve does not converge.
const float inflexion = gfxPrefs::APZChromeFlingPhysicsInflexion();
if (inflexion < 0.0f) {
return 0.0f;
}
if (inflexion > 1.0f) {
return 1.0f;
}
return inflexion;
}
// Fling scroll is stopped when the scroll position is |kThresholdForFlingEnd|
// pixels or closer from the end.
const float kThresholdForFlingEnd = 0.1;
static float GetThresholdForFlingEnd()
{
return gfxPrefs::APZChromeFlingPhysicsStopThreshold();
}
const float kTuningCoeff = ComputeDeceleration(0.84f);
static double ComputeSplineDeceleration(ParentLayerCoord aVelocity)
{
float velocityPerSec = aVelocity * 1000.0f;
return std::log(kInflexion * velocityPerSec / (kFlingFriction * kTuningCoeff));
return std::log(GetInflexion() * velocityPerSec / (GetFlingFriction() * kTuningCoeff));
}
static TimeDuration ComputeFlingDuration(ParentLayerCoord aVelocity)
@ -58,7 +77,7 @@ static TimeDuration ComputeFlingDuration(ParentLayerCoord aVelocity)
static ParentLayerCoord ComputeFlingDistance(ParentLayerCoord aVelocity)
{
const double splineDecel = ComputeSplineDeceleration(aVelocity);
return kFlingFriction * kTuningCoeff *
return GetFlingFriction() * kTuningCoeff *
std::exp(kDecelerationRate / (kDecelerationRate - 1.0) * splineDecel);
}
@ -67,8 +86,8 @@ public:
SplineConstants() {
const float kStartTension = 0.5f;
const float kEndTension = 1.0f;
const float kP1 = kStartTension * kInflexion;
const float kP2 = 1.0f - kEndTension * (1.0f - kInflexion);
const float kP1 = kStartTension * GetInflexion();
const float kP2 = 1.0f - kEndTension * (1.0f - GetInflexion());
float xMin = 0.0f;
for (int i = 0; i < kNumSamples; i++) {
@ -76,7 +95,13 @@ public:
float xMax = 1.0f;
float x, tx, coef;
while (true) {
// While the inflexion can be overridden by the user, it's clamped to
// [0,1]. For values in this range, the approximation algorithm below
// should converge in < 20 iterations. For good measure, we impose an
// iteration limit as well.
static const int sIterationLimit = 100;
int iterations = 0;
while (iterations++ < sIterationLimit) {
x = xMin + (xMax - xMin) / 2.0f;
coef = 3.0f * x * (1.0f - x);
tx = coef * ((1.0f - x) * kP1 + x * kP2) + x * x * x;
@ -178,7 +203,8 @@ bool AndroidFlingPhysics::SampleImpl(const TimeDuration& aDelta,
mCurrentPos = mTargetPos * distanceCoef;
ParentLayerPoint remainder = mTargetPos - mCurrentPos;
if (fabsf(remainder.x) < kThresholdForFlingEnd && fabsf(remainder.y) < kThresholdForFlingEnd) {
const float threshold = GetThresholdForFlingEnd();
if (fabsf(remainder.x) < threshold && fabsf(remainder.y) < threshold) {
return false;
}

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

@ -142,6 +142,21 @@ typedef PlatformSpecificStateBase PlatformSpecificState; // no extra state, jus
* If set to true, APZ uses a fling physical model similar to Chrome's
* on Android, rather than Android's StackScroller.
*
* \li\b apz.android.chrome_fling_physics.friction
* A tunable parameter for Chrome fling physics on Android that governs
* how quickly a fling animation slows down due to friction (and therefore
* also how far it reaches). Should be in the range [0-1].
*
* \li\b apz.android.chrome_fling_physics.inflexion
* A tunable parameter for Chrome fling physics on Android that governs
* the shape of the fling curve. Should be in the range [0-1].
*
* \li\b apz.android.chrome_fling_physics.stop_threshold
* A tunable parameter for Chrome fling physics on Android that governs
* how close the fling animation has to get to its target destination
* before it stops.
* Units: ParentLayer pixels
*
* \li\b apz.autoscroll.enabled
* If set to true, autoscrolling is driven by APZ rather than the content
* process main thread.

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

@ -291,6 +291,9 @@ private:
DECL_GFX_PREF(Live, "apz.allow_immediate_handoff", APZAllowImmediateHandoff, bool, true);
DECL_GFX_PREF(Live, "apz.allow_zooming", APZAllowZooming, bool, false);
DECL_GFX_PREF(Live, "apz.android.chrome_fling_physics.enabled", APZUseChromeFlingPhysics, bool, false);
DECL_GFX_PREF(Live, "apz.android.chrome_fling_physics.friction", APZChromeFlingPhysicsFriction, float, 0.015f);
DECL_GFX_PREF(Live, "apz.android.chrome_fling_physics.inflexion", APZChromeFlingPhysicsInflexion, float, 0.35f);
DECL_GFX_PREF(Live, "apz.android.chrome_fling_physics.stop_threshold", APZChromeFlingPhysicsStopThreshold, float, 0.1f);
DECL_GFX_PREF(Live, "apz.autoscroll.enabled", APZAutoscrollEnabled, bool, false);
DECL_GFX_PREF(Live, "apz.axis_lock.breakout_angle", APZAxisBreakoutAngle, float, float(M_PI / 8.0) /* 22.5 degrees */);
DECL_GFX_PREF(Live, "apz.axis_lock.breakout_threshold", APZAxisBreakoutThreshold, float, 1.0f / 32.0f);

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

@ -627,6 +627,9 @@ pref("apz.allow_checkerboarding", true);
pref("apz.allow_immediate_handoff", true);
pref("apz.allow_zooming", false);
pref("apz.android.chrome_fling_physics.enabled", false);
pref("apz.android.chrome_fling_physics.friction", "0.015");
pref("apz.android.chrome_fling_physics.inflexion", "0.35");
pref("apz.android.chrome_fling_physics.stop_threshold", "0.1");
pref("apz.autoscroll.enabled", true);
// Whether to lock touch scrolling to one axis at a time