Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/layout/generic/ScrollVelocityQueue.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 "ScrollVelocityQueue.h"
8
9
#include "gfxPrefs.h"
10
#include "nsPresContext.h"
11
#include "nsRefreshDriver.h"
12
13
namespace mozilla {
14
namespace layout {
15
16
void
17
ScrollVelocityQueue::Sample(const nsPoint& aScrollPosition)
18
0
{
19
0
  float flingSensitivity = gfxPrefs::ScrollSnapPredictionSensitivity();
20
0
  int maxVelocity = gfxPrefs::ScrollSnapPredictionMaxVelocity();
21
0
  maxVelocity = nsPresContext::CSSPixelsToAppUnits(maxVelocity);
22
0
  int maxOffset = maxVelocity * flingSensitivity;
23
0
  TimeStamp currentRefreshTime = mPresContext->RefreshDriver()->MostRecentRefresh();
24
0
  if (mSampleTime.IsNull()) {
25
0
    mAccumulator = nsPoint();
26
0
  } else {
27
0
    uint32_t durationMs = (currentRefreshTime - mSampleTime).ToMilliseconds();
28
0
    if (durationMs > gfxPrefs::APZVelocityRelevanceTime()) {
29
0
      mAccumulator = nsPoint();
30
0
      mQueue.Clear();
31
0
    } else if (durationMs == 0) {
32
0
      mAccumulator += aScrollPosition - mLastPosition;
33
0
    } else {
34
0
      nsPoint velocity = mAccumulator * 1000 / durationMs;
35
0
      velocity.Clamp(maxVelocity);
36
0
      mQueue.AppendElement(std::make_pair(durationMs, velocity));
37
0
      mAccumulator = aScrollPosition - mLastPosition;
38
0
    }
39
0
  }
40
0
  mAccumulator.Clamp(maxOffset);
41
0
  mSampleTime = currentRefreshTime;
42
0
  mLastPosition = aScrollPosition;
43
0
  TrimQueue();
44
0
}
45
46
void
47
ScrollVelocityQueue::TrimQueue()
48
0
{
49
0
  if (mSampleTime.IsNull()) {
50
0
    // There are no samples, nothing to do here.
51
0
    return;
52
0
  }
53
0
54
0
  TimeStamp currentRefreshTime = mPresContext->RefreshDriver()->MostRecentRefresh();
55
0
  nsPoint velocity;
56
0
  uint32_t timeDelta = (currentRefreshTime - mSampleTime).ToMilliseconds();
57
0
  for (int i = mQueue.Length() - 1; i >= 0; i--) {
58
0
    timeDelta += mQueue[i].first;
59
0
    if (timeDelta >= gfxPrefs::APZVelocityRelevanceTime()) {
60
0
      // The rest of the samples have expired and should be dropped
61
0
      for (; i >= 0; i--) {
62
0
        mQueue.RemoveElementAt(0);
63
0
      }
64
0
    }
65
0
  }
66
0
}
67
68
void
69
ScrollVelocityQueue::Reset()
70
0
{
71
0
  mAccumulator = nsPoint();
72
0
  mSampleTime = TimeStamp();
73
0
  mQueue.Clear();
74
0
}
75
76
/**
77
  Calculate the velocity of the scroll frame, in appunits / second.
78
*/
79
nsPoint
80
ScrollVelocityQueue::GetVelocity()
81
0
{
82
0
  TrimQueue();
83
0
  if (mQueue.Length() == 0) {
84
0
    // If getting the scroll velocity before any scrolling has occurred,
85
0
    // the velocity must be (0, 0)
86
0
    return nsPoint();
87
0
  }
88
0
  nsPoint velocity;
89
0
  for (int i = mQueue.Length() - 1; i >= 0; i--) {
90
0
    velocity += mQueue[i].second;
91
0
  }
92
0
  return velocity / mQueue.Length();;
93
0
}
94
95
} // namespace layout
96
} // namespace mozilla
97