Source code

Revision control

Other Tools

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/. */
6
7
#include "GenericScrollAnimation.h"
8
9
#include "AsyncPanZoomController.h"
10
#include "FrameMetrics.h"
11
#include "nsPoint.h"
12
#include "ScrollAnimationPhysics.h"
13
#include "ScrollAnimationBezierPhysics.h"
14
#include "ScrollAnimationMSDPhysics.h"
15
#include "mozilla/StaticPrefs_general.h"
16
17
namespace mozilla {
18
namespace layers {
19
20
GenericScrollAnimation::GenericScrollAnimation(
21
AsyncPanZoomController& aApzc, const nsPoint& aInitialPosition,
22
const ScrollAnimationBezierPhysicsSettings& aSettings)
23
: mApzc(aApzc), mFinalDestination(aInitialPosition) {
24
if (StaticPrefs::general_smoothScroll_msdPhysics_enabled()) {
25
mAnimationPhysics = MakeUnique<ScrollAnimationMSDPhysics>(aInitialPosition);
26
} else {
27
mAnimationPhysics =
28
MakeUnique<ScrollAnimationBezierPhysics>(aInitialPosition, aSettings);
29
}
30
}
31
32
void GenericScrollAnimation::UpdateDelta(TimeStamp aTime, const nsPoint& aDelta,
33
const nsSize& aCurrentVelocity) {
34
mFinalDestination += aDelta;
35
36
Update(aTime, aCurrentVelocity);
37
}
38
39
void GenericScrollAnimation::UpdateDestination(TimeStamp aTime,
40
const nsPoint& aDestination,
41
const nsSize& aCurrentVelocity) {
42
mFinalDestination = aDestination;
43
44
Update(aTime, aCurrentVelocity);
45
}
46
47
void GenericScrollAnimation::Update(TimeStamp aTime,
48
const nsSize& aCurrentVelocity) {
49
// Clamp the final destination to the scrollable area.
50
CSSPoint clamped = CSSPoint::FromAppUnits(mFinalDestination);
51
clamped.x = mApzc.mX.ClampOriginToScrollableRect(clamped.x);
52
clamped.y = mApzc.mY.ClampOriginToScrollableRect(clamped.y);
53
mFinalDestination = CSSPoint::ToAppUnits(clamped);
54
55
mAnimationPhysics->Update(aTime, mFinalDestination, aCurrentVelocity);
56
}
57
58
bool GenericScrollAnimation::DoSample(FrameMetrics& aFrameMetrics,
59
const TimeDuration& aDelta) {
60
TimeStamp now = mApzc.GetFrameTime();
61
CSSToParentLayerScale2D zoom = aFrameMetrics.GetZoom();
62
63
// If the animation is finished, make sure the final position is correct by
64
// using one last displacement. Otherwise, compute the delta via the timing
65
// function as normal.
66
bool finished = mAnimationPhysics->IsFinished(now);
67
nsPoint sampledDest = mAnimationPhysics->PositionAt(now);
68
ParentLayerPoint displacement =
69
(CSSPoint::FromAppUnits(sampledDest) - aFrameMetrics.GetScrollOffset()) *
70
zoom;
71
72
if (finished) {
73
mApzc.mX.SetVelocity(0);
74
mApzc.mY.SetVelocity(0);
75
} else if (!IsZero(displacement)) {
76
// Convert velocity from AppUnits/Seconds to ParentLayerCoords/Milliseconds
77
nsSize velocity = mAnimationPhysics->VelocityAt(now);
78
ParentLayerPoint velocityPL =
79
CSSPoint::FromAppUnits(nsPoint(velocity.width, velocity.height)) * zoom;
80
mApzc.mX.SetVelocity(velocityPL.x / 1000.0);
81
mApzc.mY.SetVelocity(velocityPL.y / 1000.0);
82
}
83
84
// Note: we ignore overscroll for generic animations.
85
ParentLayerPoint adjustedOffset, overscroll;
86
mApzc.mX.AdjustDisplacement(
87
displacement.x, adjustedOffset.x, overscroll.x,
88
mDirectionForcedToOverscroll == Some(ScrollDirection::eHorizontal));
89
mApzc.mY.AdjustDisplacement(
90
displacement.y, adjustedOffset.y, overscroll.y,
91
mDirectionForcedToOverscroll == Some(ScrollDirection::eVertical));
92
93
// If we expected to scroll, but there's no more scroll range on either axis,
94
// then end the animation early. Note that the initial displacement could be 0
95
// if the compositor ran very quickly (<1ms) after the animation was created.
96
// When that happens we want to make sure the animation continues.
97
if (!IsZero(displacement) && IsZero(adjustedOffset)) {
98
// Nothing more to do - end the animation.
99
return false;
100
}
101
102
mApzc.ScrollBy(adjustedOffset / zoom);
103
return !finished;
104
}
105
106
bool GenericScrollAnimation::HandleScrollOffsetUpdate(
107
const Maybe<CSSPoint>& aRelativeDelta) {
108
if (aRelativeDelta) {
109
mAnimationPhysics->ApplyContentShift(*aRelativeDelta);
110
return true;
111
}
112
return false;
113
}
114
115
} // namespace layers
116
} // namespace mozilla