Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/generic/ScrollVelocityQueue.h
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
#ifndef ScrollVelocityQueue_h_
8
#define ScrollVelocityQueue_h_
9
10
#include "nsTArray.h"
11
#include "nsPoint.h"
12
#include "mozilla/TimeStamp.h"
13
14
class nsPresContext;
15
16
namespace mozilla {
17
namespace layout {
18
19
/**
20
 * ScrollVelocityQueue is used to determine the current velocity of a
21
 * scroll frame, derived from scroll position samples.
22
 *
23
 * Using the last iteration's scroll position, stored in mLastPosition, a
24
 * delta of the scroll position is calculated and accumulated in mAccumulator
25
 * until the refresh driver returns a new timestamp for MostRecentRefresh().
26
 *
27
 * When there is a new timestamp from the refresh driver, the accumulated
28
 * change in scroll position is divided by the delta of the timestamp to
29
 * get an average velocity over that period.  This velocity is pushed into
30
 * mQueue as a std::pair associating each velocity with the
31
 * duration over which it was sampled.
32
 *
33
 * Samples are removed from mQueue, leaving only those necessary to determine
34
 * the average velocity over the recent relevant period, which has a duration
35
 * set by the apz.velocity_relevance_time_ms preference.
36
 *
37
 * The velocity of each sample is clamped to a value set by the
38
 * layout.css.scroll-snap.prediction-max-velocity.
39
 *
40
 * As the average velocity will later be integrated over a duration set by
41
 * the layout.css.scroll-snap.prediction-sensitivity preference and the
42
 * velocity samples are clamped to a set value, the maximum expected scroll
43
 * offset can be calculated.  This maximum offset is used to clamp
44
 * mAccumulator, eliminating samples that would otherwise result in scroll
45
 * snap position selection that is not consistent with the user's perception
46
 * of scroll velocity.
47
 */
48
49
class ScrollVelocityQueue final {
50
public:
51
  explicit ScrollVelocityQueue(nsPresContext *aPresContext)
52
0
    : mPresContext(aPresContext) {}
53
54
  // Sample() is to be called periodically when scroll movement occurs, to
55
  // record samples of scroll position used later by GetVelocity().
56
  void Sample(const nsPoint& aScrollPosition);
57
58
  // Discards velocity samples, resulting in velocity of 0 returned by
59
  // GetVelocity until move scroll position updates.
60
  void Reset();
61
62
  // Get scroll velocity averaged from recent movement, in appunits / second
63
  nsPoint GetVelocity();
64
private:
65
  // A queue of (duration, velocity) pairs; these are the historical average
66
  // velocities over the given durations.  Durations are in milliseconds,
67
  // velocities are in app units per second.
68
  nsTArray<std::pair<uint32_t, nsPoint> > mQueue;
69
70
  // Accumulates the distance and direction travelled by the scroll frame since
71
  // mSampleTime.
72
  nsPoint mAccumulator;
73
74
  // Time that mAccumulator was last reset and began accumulating.
75
  TimeStamp mSampleTime;
76
77
  // Scroll offset at the mAccumulator was last reset and began
78
  // accumulating.
79
  nsPoint mLastPosition;
80
81
  // PresContext of the containing frame, used to get timebase
82
  nsPresContext* mPresContext;
83
84
  // Remove samples from mQueue that no longer contribute to GetVelocity()
85
  // due to their age
86
  void TrimQueue();
87
};
88
89
} // namespace layout
90
} // namespace mozilla
91
92
#endif  /* !defined(ScrollVelocityQueue_h_) */