Bug 1502638 - Guard against two samples with the same timestamp in AndroidVelocityTracker. r=kats a=jcristau
authorBotond Ballo <botond@mozilla.com>
Fri, 02 Nov 2018 18:53:16 +0000
changeset 501077 035ea5732599008612558e023ba5e84d43e43fd9
parent 501076 ab7f1db24dde0647fbe476237b6684a5201f07cb
child 501078 063b9e4ccceb439d3ec795da08924c6a70f9cd6f
push id1864
push userffxbld-merge
push dateMon, 03 Dec 2018 15:51:40 +0000
treeherdermozilla-release@f040763d99ad [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskats, jcristau
bugs1502638
milestone64.0
Bug 1502638 - Guard against two samples with the same timestamp in AndroidVelocityTracker. r=kats a=jcristau Depends on D10448 Differential Revision: https://phabricator.services.mozilla.com/D10449
gfx/layers/apz/src/AndroidVelocityTracker.cpp
--- a/gfx/layers/apz/src/AndroidVelocityTracker.cpp
+++ b/gfx/layers/apz/src/AndroidVelocityTracker.cpp
@@ -49,29 +49,40 @@ Maybe<float>
 AndroidVelocityTracker::AddPosition(ParentLayerCoord aPos,
                                     uint32_t aTimestampMs,
                                     bool aIsAxisLocked)
 {
   if ((aTimestampMs - mLastEventTime) >= kAssumePointerMoveStoppedTimeMs) {
     Clear();
   }
 
-  mLastEventTime = aTimestampMs;
-
   // If we are axis-locked, adjust the position to reflect the fact that
   // no movement is happening.
   if (aIsAxisLocked && !mHistory.IsEmpty()) {
     aPos = mHistory[mHistory.Length() - 1].second - mAdditionalDelta;
   }
 
-  mHistory.AppendElement(std::make_pair(aTimestampMs, aPos + mAdditionalDelta));
-  if (mHistory.Length() > kHistorySize) {
-    mHistory.RemoveElementAt(0);
+  aPos += mAdditionalDelta;
+
+  if (aTimestampMs == mLastEventTime) {
+    // If we get a sample with the same timestamp as the previous one,
+    // just update its position. Two samples in the history with the
+    // same timestamp can lead to things like infinite velocities.
+    if (mHistory.Length() > 0) {
+      mHistory[mHistory.Length() - 1].second = aPos;
+    }
+  } else {
+    mHistory.AppendElement(std::make_pair(aTimestampMs, aPos));
+    if (mHistory.Length() > kHistorySize) {
+      mHistory.RemoveElementAt(0);
+    }
   }
 
+  mLastEventTime = aTimestampMs;
+
   if (mHistory.Length() < 2) {
     return Nothing();
   }
 
   auto start = mHistory[mHistory.Length() - 2];
   auto end = mHistory[mHistory.Length() - 1];
   return Some((end.second - start.second) / (end.first - start.first));
 }