Bug 1876335 - use GRADLE_MAVEN_REPOSITORIES in more places. r=owlish,geckoview-review...
[gecko.git] / layout / generic / ScrollAnimationMSDPhysics.cpp
blob8f0ae32d3ba6580d42c6b4e0d77439b34e7f4fc8
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "ScrollAnimationMSDPhysics.h"
8 #include "mozilla/Logging.h"
9 #include "mozilla/StaticPrefs_general.h"
10 #include "mozilla/ToString.h"
12 static mozilla::LazyLogModule sApzMsdLog("apz.msd");
13 #define MSD_LOG(...) MOZ_LOG(sApzMsdLog, LogLevel::Debug, (__VA_ARGS__))
15 using namespace mozilla;
17 ScrollAnimationMSDPhysics::ScrollAnimationMSDPhysics(const nsPoint& aStartPos)
18 : mStartPos(aStartPos),
19 mModelX(
20 0, 0, 0,
21 StaticPrefs::general_smoothScroll_msdPhysics_regularSpringConstant(),
22 1),
23 mModelY(
24 0, 0, 0,
25 StaticPrefs::general_smoothScroll_msdPhysics_regularSpringConstant(),
26 1),
27 mIsFirstIteration(true) {}
29 void ScrollAnimationMSDPhysics::Update(const TimeStamp& aTime,
30 const nsPoint& aDestination,
31 const nsSize& aCurrentVelocity) {
32 double springConstant = ComputeSpringConstant(aTime);
34 // mLastSimulatedTime is the most recent time that this animation has been
35 // "observed" at. We don't want to update back to a state in the past, so we
36 // set mStartTime to the more recent of mLastSimulatedTime and aTime.
37 // aTime can be in the past if we're processing an input event whose internal
38 // timestamp is in the past.
39 if (mLastSimulatedTime && aTime < mLastSimulatedTime) {
40 mStartTime = mLastSimulatedTime;
41 } else {
42 mStartTime = aTime;
45 if (!mIsFirstIteration) {
46 mStartPos = PositionAt(mStartTime);
49 mLastSimulatedTime = mStartTime;
50 mDestination = aDestination;
51 mModelX = NonOscillatingAxisPhysicsMSDModel(
52 mStartPos.x, aDestination.x, aCurrentVelocity.width, springConstant, 1);
53 mModelY = NonOscillatingAxisPhysicsMSDModel(
54 mStartPos.y, aDestination.y, aCurrentVelocity.height, springConstant, 1);
55 mIsFirstIteration = false;
58 void ScrollAnimationMSDPhysics::ApplyContentShift(const CSSPoint& aShiftDelta) {
59 nsPoint shiftDelta = CSSPoint::ToAppUnits(aShiftDelta);
60 mStartPos += shiftDelta;
61 mDestination += shiftDelta;
62 TimeStamp currentTime = mLastSimulatedTime;
63 nsPoint currentPosition = PositionAt(currentTime) + shiftDelta;
64 nsSize currentVelocity = VelocityAt(currentTime);
65 double springConstant = ComputeSpringConstant(currentTime);
66 mModelX = NonOscillatingAxisPhysicsMSDModel(currentPosition.x, mDestination.x,
67 currentVelocity.width,
68 springConstant, 1);
69 mModelY = NonOscillatingAxisPhysicsMSDModel(currentPosition.y, mDestination.y,
70 currentVelocity.height,
71 springConstant, 1);
74 double ScrollAnimationMSDPhysics::ComputeSpringConstant(
75 const TimeStamp& aTime) {
76 if (!mPreviousEventTime) {
77 mPreviousEventTime = aTime;
78 mPreviousDelta = TimeDuration();
79 return StaticPrefs::
80 general_smoothScroll_msdPhysics_motionBeginSpringConstant();
83 TimeDuration delta = aTime - mPreviousEventTime;
84 TimeDuration previousDelta = mPreviousDelta;
86 mPreviousEventTime = aTime;
87 mPreviousDelta = delta;
89 double deltaMS = delta.ToMilliseconds();
90 if (deltaMS >=
91 StaticPrefs::
92 general_smoothScroll_msdPhysics_continuousMotionMaxDeltaMS()) {
93 return StaticPrefs::
94 general_smoothScroll_msdPhysics_motionBeginSpringConstant();
97 if (previousDelta &&
98 deltaMS >=
99 StaticPrefs::general_smoothScroll_msdPhysics_slowdownMinDeltaMS() &&
100 deltaMS >=
101 previousDelta.ToMilliseconds() *
102 StaticPrefs::
103 general_smoothScroll_msdPhysics_slowdownMinDeltaRatio()) {
104 // The rate of events has slowed (the time delta between events has
105 // increased) enough that we think that the current scroll motion is coming
106 // to a stop. Use a stiffer spring in order to reach the destination more
107 // quickly.
108 return StaticPrefs::
109 general_smoothScroll_msdPhysics_slowdownSpringConstant();
112 return StaticPrefs::general_smoothScroll_msdPhysics_regularSpringConstant();
115 void ScrollAnimationMSDPhysics::SimulateUntil(const TimeStamp& aTime) {
116 if (!mLastSimulatedTime || aTime <= mLastSimulatedTime) {
117 return;
119 TimeDuration delta = aTime - mLastSimulatedTime;
120 mModelX.Simulate(delta);
121 mModelY.Simulate(delta);
122 mLastSimulatedTime = aTime;
123 MSD_LOG("Simulated for duration %f, finished %d position %s velocity %s\n",
124 delta.ToMilliseconds(), IsFinished(aTime),
125 ToString(CSSPoint::FromAppUnits(PositionAt(aTime))).c_str(),
126 ToString(CSSPoint::FromAppUnits(VelocityAt(aTime))).c_str());
129 nsPoint ScrollAnimationMSDPhysics::PositionAt(const TimeStamp& aTime) {
130 SimulateUntil(aTime);
131 return nsPoint(NSToCoordRound(mModelX.GetPosition()),
132 NSToCoordRound(mModelY.GetPosition()));
135 nsSize ScrollAnimationMSDPhysics::VelocityAt(const TimeStamp& aTime) {
136 SimulateUntil(aTime);
137 return nsSize(NSToCoordRound(mModelX.GetVelocity()),
138 NSToCoordRound(mModelY.GetVelocity()));
141 static double ClampVelocityToMaximum(double aVelocity, double aInitialPosition,
142 double aDestination,
143 double aSpringConstant) {
144 // Clamp velocity to the maximum value it could obtain if we started at this
145 // position with zero velocity (see bug 1866904 comment 3). With a damping
146 // ratio >= 1.0, this should be low enough to avoid overshooting the
147 // destination.
148 double velocityLimit =
149 sqrt(aSpringConstant) * abs(aDestination - aInitialPosition);
150 return clamped(aVelocity, -velocityLimit, velocityLimit);
153 ScrollAnimationMSDPhysics::NonOscillatingAxisPhysicsMSDModel::
154 NonOscillatingAxisPhysicsMSDModel(double aInitialPosition,
155 double aInitialDestination,
156 double aInitialVelocity,
157 double aSpringConstant,
158 double aDampingRatio)
159 : AxisPhysicsMSDModel(
160 aInitialPosition, aInitialDestination,
161 ClampVelocityToMaximum(aInitialVelocity, aInitialPosition,
162 aInitialDestination, aSpringConstant),
163 aSpringConstant, aDampingRatio) {
164 MSD_LOG("Constructing axis physics model with parameters %f %f %f %f %f\n",
165 aInitialPosition, aInitialDestination, aInitialVelocity,
166 aSpringConstant, aDampingRatio);
167 MOZ_ASSERT(aDampingRatio >= 1.0,
168 "Damping ratio must be >= 1.0 to avoid oscillation");