Bug 949859 - When calculating fling velocity, ignore timestamps that are too old. r=botond

This commit is contained in:
Kartikaya Gupta 2014-05-27 11:45:03 -04:00
parent f3e5d4a468
commit a34febcbdd
4 changed files with 26 additions and 13 deletions

View File

@ -245,6 +245,12 @@ typedef GeckoContentController::APZStateChange APZStateChange;
* How much to adjust the displayport in the direction of scrolling. This value
* is multiplied by the velocity and added to the displayport offset.
*
* "apz.velocity_relevance_time_ms"
* When computing a fling velocity from the most recently stored velocity
* information, only velocities within the most X milliseconds are used.
* This pref controls the value of X.
* Units: ms
*
* "apz.x_skate_size_multiplier", "apz.y_skate_size_multiplier"
* The multiplier we apply to the displayport size if it is skating (current
* velocity is above apz.min_skate_speed). We prefer to increase the size of the
@ -882,8 +888,8 @@ nsEventStatus AsyncPanZoomController::OnTouchEnd(const MultiTouchInput& aEvent)
}
}
}
mX.EndTouch();
mY.EndTouch();
mX.EndTouch(aEvent.mTime);
mY.EndTouch(aEvent.mTime);
SetState(FLING);
StartAnimation(new FlingAnimation(*this,
true /* apply acceleration */,

View File

@ -49,7 +49,7 @@ void Axis::UpdateWithTouchAtDevicePoint(int32_t aPos, uint32_t aTimestampMs) {
mPosTimeMs = aTimestampMs;
// Limit queue size pased on pref
mVelocityQueue.AppendElement(mVelocity);
mVelocityQueue.AppendElement(std::make_pair(aTimestampMs, mVelocity));
if (mVelocityQueue.Length() > gfxPrefs::APZMaxVelocityQueueSize()) {
mVelocityQueue.RemoveElementAt(0);
}
@ -179,15 +179,18 @@ float Axis::PanDistance(float aPos) {
return fabsf(aPos - mStartPos);
}
void Axis::EndTouch() {
// Calculate the mean velocity and empty the queue.
int count = mVelocityQueue.Length();
if (count) {
mVelocity = 0;
while (!mVelocityQueue.IsEmpty()) {
mVelocity += mVelocityQueue[0];
mVelocityQueue.RemoveElementAt(0);
void Axis::EndTouch(uint32_t aTimestampMs) {
mVelocity = 0;
int count = 0;
while (!mVelocityQueue.IsEmpty()) {
uint32_t timeDelta = (aTimestampMs - mVelocityQueue[0].first);
if (timeDelta < gfxPrefs::APZVelocityRelevanceTime()) {
count++;
mVelocity += mVelocityQueue[0].second;
}
mVelocityQueue.RemoveElementAt(0);
}
if (count > 1) {
mVelocity /= count;
}
}

View File

@ -67,7 +67,7 @@ public:
* Notify this Axis that a touch has ended gracefully. This may perform
* recalculations of the axis velocity.
*/
void EndTouch();
void EndTouch(uint32_t aTimestampMs);
/**
* Notify this Axis that a touch has ended forcefully. Useful for stopping
@ -222,7 +222,10 @@ protected:
// its maximum value if mOverscroll is positive, and at its minimum value
// if mOverscroll is negative).
float mOverscroll;
nsTArray<float> mVelocityQueue;
// A queue of (timestamp, velocity) pairs; these are the historical
// velocities at the given timestamps. Timestamps are in milliseconds,
// velocities are in screen pixels per ms.
nsTArray<std::pair<uint32_t, float> > mVelocityQueue;
const FrameMetrics& GetFrameMetrics() const;

View File

@ -129,6 +129,7 @@ private:
DECL_GFX_PREF(Live, "apz.touch_start_tolerance", APZTouchStartTolerance, float, 1.0f/4.5f);
DECL_GFX_PREF(Live, "apz.use_paint_duration", APZUsePaintDuration, bool, true);
DECL_GFX_PREF(Live, "apz.velocity_bias", APZVelocityBias, float, 1.0f);
DECL_GFX_PREF(Live, "apz.velocity_relevance_time_ms", APZVelocityRelevanceTime, uint32_t, 150);
DECL_GFX_PREF(Live, "apz.x_skate_size_multiplier", APZXSkateSizeMultiplier, float, 1.5f);
DECL_GFX_PREF(Live, "apz.x_stationary_size_multiplier", APZXStationarySizeMultiplier, float, 3.0f);
DECL_GFX_PREF(Live, "apz.y_skate_size_multiplier", APZYSkateSizeMultiplier, float, 2.5f);