Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/generic/ScrollAnimationMSDPhysics.cpp
Line
Count
Source (jump to first uncovered line)
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 "ScrollAnimationMSDPhysics.h"
8
#include "gfxPrefs.h"
9
10
using namespace mozilla;
11
12
ScrollAnimationMSDPhysics::ScrollAnimationMSDPhysics(const nsPoint& aStartPos)
13
 : mStartPos(aStartPos)
14
 , mModelX(0, 0, 0, gfxPrefs::SmoothScrollMSDPhysicsRegularSpringConstant(), 1)
15
 , mModelY(0, 0, 0, gfxPrefs::SmoothScrollMSDPhysicsRegularSpringConstant(), 1)
16
 , mIsFirstIteration(true)
17
0
{
18
0
}
19
20
void
21
ScrollAnimationMSDPhysics::Update(const TimeStamp& aTime,
22
                                  const nsPoint& aDestination,
23
                                  const nsSize& aCurrentVelocity)
24
0
{
25
0
  double springConstant = ComputeSpringConstant(aTime);
26
0
27
0
  // mLastSimulatedTime is the most recent time that this animation has been
28
0
  // "observed" at. We don't want to update back to a state in the past, so we
29
0
  // set mStartTime to the more recent of mLastSimulatedTime and aTime.
30
0
  // aTime can be in the past if we're processing an input event whose internal
31
0
  // timestamp is in the past.
32
0
  if (mLastSimulatedTime && aTime < mLastSimulatedTime) {
33
0
    mStartTime = mLastSimulatedTime;
34
0
  } else {
35
0
    mStartTime = aTime;
36
0
  }
37
0
38
0
  if (!mIsFirstIteration) {
39
0
    mStartPos = PositionAt(mStartTime);
40
0
  }
41
0
42
0
  mLastSimulatedTime = mStartTime;
43
0
  mDestination = aDestination;
44
0
  mModelX = AxisPhysicsMSDModel(mStartPos.x, aDestination.x,
45
0
                                aCurrentVelocity.width, springConstant, 1);
46
0
  mModelY = AxisPhysicsMSDModel(mStartPos.y, aDestination.y,
47
0
                                aCurrentVelocity.height, springConstant, 1);
48
0
  mIsFirstIteration = false;
49
0
}
50
51
double
52
ScrollAnimationMSDPhysics::ComputeSpringConstant(const TimeStamp& aTime)
53
0
{
54
0
  if (!mPreviousEventTime) {
55
0
    mPreviousEventTime = aTime;
56
0
    mPreviousDelta = TimeDuration();
57
0
    return gfxPrefs::SmoothScrollMSDPhysicsMotionBeginSpringConstant();
58
0
  }
59
0
60
0
  TimeDuration delta = aTime - mPreviousEventTime;
61
0
  TimeDuration previousDelta = mPreviousDelta;
62
0
63
0
  mPreviousEventTime = aTime;
64
0
  mPreviousDelta = delta;
65
0
66
0
  double deltaMS = delta.ToMilliseconds();
67
0
  if (deltaMS >= gfxPrefs::SmoothScrollMSDPhysicsContinuousMotionMaxDeltaMS()) {
68
0
    return gfxPrefs::SmoothScrollMSDPhysicsMotionBeginSpringConstant();
69
0
  }
70
0
71
0
  if (previousDelta &&
72
0
      deltaMS >= gfxPrefs::SmoothScrollMSDPhysicsSlowdownMinDeltaMS() &&
73
0
      deltaMS >= previousDelta.ToMilliseconds() * gfxPrefs::SmoothScrollMSDPhysicsSlowdownMinDeltaRatio()) {
74
0
    // The rate of events has slowed (the time delta between events has
75
0
    // increased) enough that we think that the current scroll motion is coming
76
0
    // to a stop. Use a stiffer spring in order to reach the destination more
77
0
    // quickly.
78
0
    return gfxPrefs::SmoothScrollMSDPhysicsSlowdownSpringConstant();
79
0
  }
80
0
81
0
  return gfxPrefs::SmoothScrollMSDPhysicsRegularSpringConstant();
82
0
}
83
84
void
85
ScrollAnimationMSDPhysics::SimulateUntil(const TimeStamp& aTime)
86
0
{
87
0
  if (!mLastSimulatedTime || aTime < mLastSimulatedTime) {
88
0
    return;
89
0
  }
90
0
  TimeDuration delta = aTime - mLastSimulatedTime;
91
0
  mModelX.Simulate(delta);
92
0
  mModelY.Simulate(delta);
93
0
  mLastSimulatedTime = aTime;
94
0
}
95
96
nsPoint
97
ScrollAnimationMSDPhysics::PositionAt(const TimeStamp& aTime)
98
0
{
99
0
  SimulateUntil(aTime);
100
0
  return nsPoint(NSToCoordRound(mModelX.GetPosition()),
101
0
                 NSToCoordRound(mModelY.GetPosition()));
102
0
}
103
104
nsSize
105
ScrollAnimationMSDPhysics::VelocityAt(const TimeStamp& aTime)
106
0
{
107
0
  SimulateUntil(aTime);
108
0
  return nsSize(NSToCoordRound(mModelX.GetVelocity()),
109
0
                NSToCoordRound(mModelY.GetVelocity()));
110
0
}