Backed out changeset 496886cb30a5 (bug 1867152) for bc failures on browser_user_input...
[gecko.git] / layout / generic / ScrollVelocityQueue.h
blob86791e866d8ba1983f725edf083e17b2a45fd001
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 #ifndef ScrollVelocityQueue_h_
8 #define ScrollVelocityQueue_h_
10 #include "nsTArray.h"
11 #include "nsPoint.h"
12 #include "mozilla/TimeStamp.h"
14 class nsPresContext;
16 namespace mozilla {
17 namespace layout {
19 /**
20 * ScrollVelocityQueue is used to determine the current velocity of a
21 * scroll frame, derived from scroll position samples.
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().
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.
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.
37 * The velocity of each sample is clamped to a value set by the
38 * layout.css.scroll-snap.prediction-max-velocity.
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.
49 class ScrollVelocityQueue final {
50 public:
51 explicit ScrollVelocityQueue(nsPresContext* aPresContext)
52 : mPresContext(aPresContext) {}
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);
58 // Discards velocity samples, resulting in velocity of 0 returned by
59 // GetVelocity until move scroll position updates.
60 void Reset();
62 // Get scroll velocity averaged from recent movement, in appunits / second
63 nsPoint GetVelocity();
65 private:
66 // A queue of (duration, velocity) pairs; these are the historical average
67 // velocities over the given durations. Durations are in milliseconds,
68 // velocities are in app units per second.
69 nsTArray<std::pair<uint32_t, nsPoint> > mQueue;
71 // Accumulates the distance and direction travelled by the scroll frame since
72 // mSampleTime.
73 nsPoint mAccumulator;
75 // Time that mAccumulator was last reset and began accumulating.
76 TimeStamp mSampleTime;
78 // Scroll offset at the mAccumulator was last reset and began
79 // accumulating.
80 nsPoint mLastPosition;
82 // PresContext of the containing frame, used to get timebase
83 nsPresContext* mPresContext;
85 // Remove samples from mQueue that no longer contribute to GetVelocity()
86 // due to their age
87 void TrimQueue();
90 } // namespace layout
91 } // namespace mozilla
93 #endif /* !defined(ScrollVelocityQueue_h_) */