Bug 1016035 - Make the threshold in AxisPhysicsMSDModel::IsFinished controllable by the caller. r=kip

This commit is contained in:
Markus Stange 2015-08-04 16:11:37 -04:00
parent fc42433f35
commit 3e3f8580f9
4 changed files with 23 additions and 23 deletions

View File

@ -70,30 +70,23 @@ AxisPhysicsMSDModel::SetDestination(double aDestination)
}
bool
AxisPhysicsMSDModel::IsFinished()
AxisPhysicsMSDModel::IsFinished(double aSmallestVisibleIncrement)
{
// In order to satisfy the condition of reaching the destination, the distance
// between the simulation position and the destination must be less than
// kFinishDistance while the speed is simultaneously less than
// kFinishVelocity. This enables an under-damped system to overshoot the
// aSmallestVisibleIncrement while the speed is simultaneously less than
// finishVelocity. This enables an under-damped system to overshoot the
// destination when desired without prematurely triggering the finished state.
// As the number of app units per css pixel is 60 and retina / HiDPI displays
// may display two pixels for every css pixel, setting kFinishDistance to 30.0
// ensures that there will be no perceptable shift in position at the end
// of the animation.
const double kFinishDistance = 30.0;
// If kFinishVelocity is set too low, the animation may end long after
// If finishVelocity is set too low, the animation may end long after
// oscillation has finished, resulting in unnecessary processing.
// If set too high, the animation may prematurely terminate when expected
// to overshoot the destination in an under-damped system.
// 60.0 was selected through experimentation that revealed that a
// critically damped system will terminate within 100ms.
const double kFinishVelocity = 60.0;
// aSmallestVisibleIncrement * 2 was selected through experimentation that
// revealed that a critically damped system will terminate within 100ms.
const double finishVelocity = aSmallestVisibleIncrement * 2;
return fabs(mDestination - GetPosition ()) < kFinishDistance
&& fabs(GetVelocity()) <= kFinishVelocity;
return fabs(mDestination - GetPosition ()) < aSmallestVisibleIncrement
&& fabs(GetVelocity()) <= finishVelocity;
}
} // namespace layers

View File

@ -38,7 +38,7 @@ public:
* Returns true when the position is close to the destination and the
* velocity is low.
*/
bool IsFinished();
bool IsFinished(double aSmallestVisibleIncrement);
protected:
virtual double Acceleration(const State &aState);

View File

@ -695,7 +695,10 @@ public:
* or false if the smooth scroll has ended.
*/
bool DoSample(FrameMetrics& aFrameMetrics, const TimeDuration& aDelta) {
if (mXAxisModel.IsFinished() && mYAxisModel.IsFinished()) {
nsPoint oneParentLayerPixel =
CSSPoint::ToAppUnits(ParentLayerPoint(1, 1) / aFrameMetrics.GetZoom());
if (mXAxisModel.IsFinished(oneParentLayerPixel.x) &&
mYAxisModel.IsFinished(oneParentLayerPixel.y)) {
return false;
}
@ -712,12 +715,12 @@ public:
// Keep the velocity updated for the Axis class so that any animations
// chained off of the smooth scroll will inherit it.
if (mXAxisModel.IsFinished()) {
if (mXAxisModel.IsFinished(oneParentLayerPixel.x)) {
mApzc.mX.SetVelocity(0);
} else {
mApzc.mX.SetVelocity(velocity.x);
}
if (mYAxisModel.IsFinished()) {
if (mYAxisModel.IsFinished(oneParentLayerPixel.y)) {
mApzc.mY.SetVelocity(0);
} else {
mApzc.mY.SetVelocity(velocity.y);

View File

@ -1474,7 +1474,8 @@ public:
const nsPoint &aInitialDestination,
const nsSize &aInitialVelocity,
const nsRect &aRange,
const mozilla::TimeStamp &aStartTime)
const mozilla::TimeStamp &aStartTime,
nsPresContext* aPresContext)
: mXAxisModel(aInitialPosition.x, aInitialDestination.x,
aInitialVelocity.width,
gfxPrefs::ScrollBehaviorSpringConstant(),
@ -1486,6 +1487,7 @@ public:
, mRange(aRange)
, mLastRefreshTime(aStartTime)
, mCallee(nullptr)
, mOneDevicePixelInAppUnits(aPresContext->DevPixelsToAppUnits(1))
{
}
@ -1542,7 +1544,8 @@ public:
bool IsFinished()
{
return mXAxisModel.IsFinished() && mYAxisModel.IsFinished();
return mXAxisModel.IsFinished(mOneDevicePixelInAppUnits) &&
mYAxisModel.IsFinished(mOneDevicePixelInAppUnits);
}
virtual void WillRefresh(mozilla::TimeStamp aTime) override {
@ -1595,6 +1598,7 @@ private:
nsRect mRange;
mozilla::TimeStamp mLastRefreshTime;
ScrollFrameHelper *mCallee;
nscoord mOneDevicePixelInAppUnits;
};
// AsyncScroll has ref counting.
@ -2069,7 +2073,7 @@ ScrollFrameHelper::ScrollToWithOrigin(nsPoint aScrollPosition,
mAsyncSmoothMSDScroll =
new AsyncSmoothMSDScroll(GetScrollPosition(), mDestination,
currentVelocity, GetScrollRangeForClamping(),
now);
now, presContext);
if (!mAsyncSmoothMSDScroll->SetRefreshObserver(this)) {
// Observer setup failed. Scroll the normal way.