Bug 1448439 - Use an accurate pixels per pinch value in AndroidFlingPhysics. r=kats

MozReview-Commit-ID: I0yZKTvlHWV

--HG--
extra : rebase_source : 89f751e48e376812c49fc2d7665a43049d9de121
This commit is contained in:
Botond Ballo 2018-04-26 16:42:05 -04:00
Родитель 67bc5921a7
Коммит 04287e6502
8 изменённых файлов: 64 добавлений и 28 удалений

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

@ -47,12 +47,14 @@ AndroidSpecificState::AndroidSpecificState() {
AsyncPanZoomAnimation*
AndroidSpecificState::CreateFlingAnimation(AsyncPanZoomController& aApzc,
const FlingHandoffState& aHandoffState) {
const FlingHandoffState& aHandoffState,
float aPLPPI) {
if (gfxPrefs::APZUseChromeFlingPhysics()) {
return new GenericFlingAnimation<AndroidFlingPhysics>(aApzc,
aHandoffState.mChain,
aHandoffState.mIsHandoff,
aHandoffState.mScrolledApzc);
aHandoffState.mScrolledApzc,
aPLPPI);
} else {
return new StackScrollerFlingAnimation(aApzc,
this,

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

@ -23,7 +23,8 @@ public:
}
virtual AsyncPanZoomAnimation* CreateFlingAnimation(AsyncPanZoomController& aApzc,
const FlingHandoffState& aHandoffState) override;
const FlingHandoffState& aHandoffState,
float aPLPPI) override;
static void InitializeGlobalState();

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

@ -18,13 +18,14 @@ namespace layers {
// Chrome's implementation of fling physics on Android:
// https://cs.chromium.org/chromium/src/ui/events/android/scroller.cc?rcl=3ae3aaff927038a5c644926842cb0c31dea60c79
static double ComputeDeceleration(float aFriction)
static double ComputeDeceleration(float aDPI)
{
const float kFriction = 0.84f;
const float kGravityEarth = 9.80665f;
return kGravityEarth // g (m/s^2)
* 39.37f // inch/meter
* 160.f // pixels/inch
* aFriction;
* aDPI // pixels/inch
* kFriction;
}
// == std::log(0.78f) / std::log(0.9f)
@ -59,25 +60,23 @@ static float GetThresholdForFlingEnd()
return gfxPrefs::APZChromeFlingPhysicsStopThreshold();
}
const float kTuningCoeff = ComputeDeceleration(0.84f);
static double ComputeSplineDeceleration(ParentLayerCoord aVelocity)
static double ComputeSplineDeceleration(ParentLayerCoord aVelocity, double aTuningCoeff)
{
float velocityPerSec = aVelocity * 1000.0f;
return std::log(GetInflexion() * velocityPerSec / (GetFlingFriction() * kTuningCoeff));
return std::log(GetInflexion() * velocityPerSec / (GetFlingFriction() * aTuningCoeff));
}
static TimeDuration ComputeFlingDuration(ParentLayerCoord aVelocity)
static TimeDuration ComputeFlingDuration(ParentLayerCoord aVelocity, double aTuningCoeff)
{
const double splineDecel = ComputeSplineDeceleration(aVelocity);
const double splineDecel = ComputeSplineDeceleration(aVelocity, aTuningCoeff);
const double timeSeconds = std::exp(splineDecel / (kDecelerationRate - 1.0));
return TimeDuration::FromSeconds(timeSeconds);
}
static ParentLayerCoord ComputeFlingDistance(ParentLayerCoord aVelocity)
static ParentLayerCoord ComputeFlingDistance(ParentLayerCoord aVelocity, double aTuningCoeff)
{
const double splineDecel = ComputeSplineDeceleration(aVelocity);
return GetFlingFriction() * kTuningCoeff *
const double splineDecel = ComputeSplineDeceleration(aVelocity, aTuningCoeff);
return GetFlingFriction() * aTuningCoeff *
std::exp(kDecelerationRate / (kDecelerationRate - 1.0) * splineDecel);
}
@ -148,17 +147,19 @@ StaticAutoPtr<SplineConstants> gSplineConstants;
ClearOnShutdown(&gSplineConstants);
}
void AndroidFlingPhysics::Init(const ParentLayerPoint& aStartingVelocity)
void AndroidFlingPhysics::Init(const ParentLayerPoint& aStartingVelocity,
float aPLPPI)
{
mVelocity = aStartingVelocity.Length();
mTargetDuration = ComputeFlingDuration(mVelocity);
const double tuningCoeff = ComputeDeceleration(aPLPPI);
mTargetDuration = ComputeFlingDuration(mVelocity, tuningCoeff);
MOZ_ASSERT(!mTargetDuration.IsZero());
mDurationSoFar = TimeDuration();
mLastPos = ParentLayerPoint();
mCurrentPos = ParentLayerPoint();
float coeffX = mVelocity == 0 ? 1.0f : aStartingVelocity.x / mVelocity;
float coeffY = mVelocity == 0 ? 1.0f : aStartingVelocity.y / mVelocity;
mTargetDistance = ComputeFlingDistance(mVelocity);
mTargetDistance = ComputeFlingDistance(mVelocity, tuningCoeff);
mTargetPos = ParentLayerPoint(mTargetDistance * coeffX,
mTargetDistance * coeffY);
const float hyp = mTargetPos.Length();

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

@ -17,7 +17,7 @@ namespace layers {
class AndroidFlingPhysics {
public:
void Init(const ParentLayerPoint& aVelocity);
void Init(const ParentLayerPoint& aVelocity, float aPLPPI);
void Sample(const TimeDuration& aDelta,
ParentLayerPoint* aOutVelocity,
ParentLayerPoint* aOutOffset);

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

@ -536,12 +536,14 @@ static uint32_t sAsyncPanZoomControllerCount = 0;
AsyncPanZoomAnimation*
PlatformSpecificStateBase::CreateFlingAnimation(AsyncPanZoomController& aApzc,
const FlingHandoffState& aHandoffState)
const FlingHandoffState& aHandoffState,
float aPLPPI)
{
return new GenericFlingAnimation<DesktopFlingPhysics>(aApzc,
aHandoffState.mChain,
aHandoffState.mIsHandoff,
aHandoffState.mScrolledApzc);
aHandoffState.mScrolledApzc,
aPLPPI);
}
TimeStamp
@ -3015,6 +3017,11 @@ RefPtr<const OverscrollHandoffChain> AsyncPanZoomController::BuildOverscrollHand
}
ParentLayerPoint AsyncPanZoomController::AttemptFling(const FlingHandoffState& aHandoffState) {
// The PLPPI computation acquires the tree lock, so it needs to be performed
// on the controller thread, and before the APZC lock is acquired.
APZThreadUtils::AssertOnControllerThread();
float PLPPI = ComputePLPPI(PanStart(), aHandoffState.mVelocity);
RecursiveMutexAutoLock lock(mRecursiveMutex);
if (!IsPannable()) {
@ -3041,13 +3048,29 @@ ParentLayerPoint AsyncPanZoomController::AttemptFling(const FlingHandoffState& a
ScrollSnapToDestination();
if (mState != SMOOTH_SCROLL) {
SetState(FLING);
AsyncPanZoomAnimation* fling = GetPlatformSpecificState()->CreateFlingAnimation(*this, aHandoffState);
AsyncPanZoomAnimation* fling = GetPlatformSpecificState()->CreateFlingAnimation(
*this, aHandoffState, PLPPI);
StartAnimation(fling);
}
return residualVelocity;
}
float AsyncPanZoomController::ComputePLPPI(ParentLayerPoint aPoint, ParentLayerPoint aDirection) const
{
// Convert |aDirection| into a unit vector.
aDirection = aDirection / aDirection.Length();
// Place the vector at |aPoint| and convert to screen coordinates.
// The length of the resulting vector is the number of Screen coordinates
// that equal 1 ParentLayer coordinate in the given direction.
float screenPerParent = ToScreenCoordinates(aDirection, aPoint).Length();
// Finally, factor in the DPI scale.
return GetDPI() / screenPerParent;
}
ParentLayerPoint AsyncPanZoomController::AdjustHandoffVelocityForOverscrollBehavior(ParentLayerPoint& aHandoffVelocity) const
{
RecursiveMutexAutoLock lock(mRecursiveMutex);

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

@ -71,8 +71,10 @@ class PlatformSpecificStateBase {
public:
virtual ~PlatformSpecificStateBase() = default;
virtual AndroidSpecificState* AsAndroidSpecificState() { return nullptr; }
// PLPPI = "ParentLayer pixels per (Screen) inch"
virtual AsyncPanZoomAnimation* CreateFlingAnimation(AsyncPanZoomController& aApzc,
const FlingHandoffState& aHandoffState);
const FlingHandoffState& aHandoffState,
float aPLPPI);
static void InitializeGlobalState() {}
};
@ -1207,6 +1209,10 @@ private:
// Invoked by the pinch repaint timer.
void DoDelayedRequestContentRepaint();
// Compute the number of ParentLayer pixels per (Screen) inch at the given
// point and in the given direction.
float ComputePLPPI(ParentLayerPoint aPoint, ParentLayerPoint aDirection) const;
/* ===================================================================
* The functions and members in this section are used to make ancestor chains
* out of APZC instances. These chains can only be walked or manipulated

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

@ -20,7 +20,7 @@ namespace layers {
class DesktopFlingPhysics {
public:
void Init(const ParentLayerPoint& aStartingVelocity)
void Init(const ParentLayerPoint& aStartingVelocity, float aPLPPI /* unused */)
{
mVelocity = aStartingVelocity;
}

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

@ -33,8 +33,10 @@ namespace layers {
*
* - Default constructor.
*
* - Init(const ParentLayerPoint& aStartingVelocity).
* Called at the beginning of the fling, with the fling's starting velocity.
* - Init(const ParentLayerPoint& aStartingVelocity, float aPLPPI).
* Called at the beginning of the fling, with the fling's starting velocity,
* and the number of ParentLayer pixels per (Screen) inch at the point of
* the fling's start in the fling's direction.
*
* - Sample(const TimeDuration& aDelta,
* ParentLayerPoint* aOutVelocity,
@ -54,7 +56,8 @@ public:
GenericFlingAnimation(AsyncPanZoomController& aApzc,
const RefPtr<const OverscrollHandoffChain>& aOverscrollHandoffChain,
bool aFlingIsHandedOff,
const RefPtr<const AsyncPanZoomController>& aScrolledApzc)
const RefPtr<const AsyncPanZoomController>& aScrolledApzc,
float aPLPPI)
: mApzc(aApzc)
, mOverscrollHandoffChain(aOverscrollHandoffChain)
, mScrolledApzc(aScrolledApzc)
@ -107,7 +110,7 @@ public:
mApzc.mLastFlingTime = now;
mApzc.mLastFlingVelocity = velocity;
FlingPhysics::Init(mApzc.GetVelocityVector());
FlingPhysics::Init(mApzc.GetVelocityVector(), aPLPPI);
}
/**