ScrollVelocityQueue.h 3.4 KB

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