15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/events/gesture_detection/motion_event_buffer.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "base/debug/trace_event.h" 83551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/events/gesture_detection/motion_event.h" 93551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "ui/events/gesture_detection/motion_event_generic.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace ui { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 13868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Latency added during resampling. A few milliseconds doesn't hurt much but 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reduces the impact of mispredicted touch positions. 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kResampleLatencyMs = 5; 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Minimum time difference between consecutive samples before attempting to 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// resample. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kResampleMinDeltaMs = 2; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Maximum time to predict forward from the last known state, to avoid 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// predicting too far into the future. This time is further bounded by 50% of 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the last time delta. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kResampleMaxPredictionMs = 8; 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdochtypedef ScopedVector<MotionEvent> MotionEventVector; 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdochfloat Lerp(float a, float b, float alpha) { 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return a + alpha * (b - a); 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool CanAddSample(const MotionEvent& event0, const MotionEvent& event1) { 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(event0.GetAction(), MotionEvent::ACTION_MOVE); 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (event1.GetAction() != MotionEvent::ACTION_MOVE) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t pointer_count = event0.GetPointerCount(); 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (pointer_count != event1.GetPointerCount()) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t event0_i = 0; event0_i < pointer_count; ++event0_i) { 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int id = event0.GetPointerId(event0_i); 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int event1_i = event1.FindPointerIndexOfId(id); 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (event1_i == -1) 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (event0.GetToolType(event0_i) != event1.GetToolType(event1_i)) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ShouldResampleTool(MotionEvent::ToolType tool) { 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return tool == MotionEvent::TOOL_TYPE_UNKNOWN || 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) tool == MotionEvent::TOOL_TYPE_FINGER; 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)size_t CountSamplesNoLaterThan(const MotionEventVector& batch, 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks time) { 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t count = 0; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (count < batch.size() && batch[count]->GetEventTime() <= time) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++count; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return count; 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MotionEventVector ConsumeSamplesNoLaterThan(MotionEventVector* batch, 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks time) { 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(batch); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t count = CountSamplesNoLaterThan(*batch, time); 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GE(batch->size(), count); 72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (count == 0) 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return MotionEventVector(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (count == batch->size()) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return batch->Pass(); 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 78c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(jdduke): Use a ScopedDeque to work around this mess. 79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MotionEventVector unconsumed_batch; 80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unconsumed_batch.insert( 81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unconsumed_batch.begin(), batch->begin() + count, batch->end()); 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) batch->weak_erase(batch->begin() + count, batch->end()); 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) unconsumed_batch.swap(*batch); 85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_GE(unconsumed_batch.size(), 1U); 86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return unconsumed_batch.Pass(); 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PointerProperties PointerFromMotionEvent(const MotionEvent& event, 90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t pointer_index) { 91c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PointerProperties result; 92c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result.id = event.GetPointerId(pointer_index); 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result.tool_type = event.GetToolType(pointer_index); 94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result.x = event.GetX(pointer_index); 95c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result.y = event.GetY(pointer_index); 96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result.raw_x = event.GetRawX(pointer_index); 97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result.raw_y = event.GetRawY(pointer_index); 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result.pressure = event.GetPressure(pointer_index); 99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result.touch_major = event.GetTouchMajor(pointer_index); 100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result.touch_minor = event.GetTouchMinor(pointer_index); 101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) result.orientation = event.GetOrientation(pointer_index); 102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return result; 103c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 104c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 105c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)PointerProperties ResamplePointer(const MotionEvent& event0, 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const MotionEvent& event1, 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t event0_pointer_index, 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) size_t event1_pointer_index, 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) float alpha) { 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(event0.GetPointerId(event0_pointer_index), 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) event1.GetPointerId(event1_pointer_index)); 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // If the tool should not be resampled, use the latest event in the valid 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // horizon (i.e., the event no later than the time interpolated by alpha). 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!ShouldResampleTool(event0.GetToolType(event0_pointer_index))) { 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (alpha > 1) 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return PointerFromMotionEvent(event1, event1_pointer_index); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) else 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return PointerFromMotionEvent(event0, event0_pointer_index); 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) PointerProperties p(PointerFromMotionEvent(event0, event0_pointer_index)); 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) p.x = Lerp(p.x, event1.GetX(event1_pointer_index), alpha); 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) p.y = Lerp(p.y, event1.GetY(event1_pointer_index), alpha); 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) p.raw_x = Lerp(p.raw_x, event1.GetRawX(event1_pointer_index), alpha); 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) p.raw_y = Lerp(p.raw_y, event1.GetRawY(event1_pointer_index), alpha); 126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return p; 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<MotionEvent> ResampleMotionEvent(const MotionEvent& event0, 13058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const MotionEvent& event1, 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks resample_time) { 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(MotionEvent::ACTION_MOVE, event0.GetAction()); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(event0.GetPointerCount(), event1.GetPointerCount()); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::TimeTicks time0 = event0.GetEventTime(); 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::TimeTicks time1 = event1.GetEventTime(); 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(time0 < time1); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(time0 <= resample_time); 13958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const float alpha = (resample_time - time0).InMillisecondsF() / 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) (time1 - time0).InMillisecondsF(); 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<MotionEventGeneric> event; 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t pointer_count = event0.GetPointerCount(); 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(pointer_count, event1.GetPointerCount()); 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t event0_i = 0; event0_i < pointer_count; ++event0_i) { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int event1_i = event1.FindPointerIndexOfId(event0.GetPointerId(event0_i)); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_NE(event1_i, -1); 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PointerProperties pointer = ResamplePointer( 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event0, event1, event0_i, static_cast<size_t>(event1_i), alpha); 15158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 15258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (event0_i == 0) { 15358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) event.reset(new MotionEventGeneric( 15458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) MotionEvent::ACTION_MOVE, resample_time, pointer)); 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) event->PushPointer(pointer); 15758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 15858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(event); 161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) event->set_id(event0.GetId()); 162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) event->set_action_index(event0.GetActionIndex()); 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) event->set_button_state(event0.GetButtonState()); 164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return event.PassAs<MotionEvent>(); 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MotionEvent implementation for storing multiple events, with the most 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// recent event used as the base event, and prior events used as the history. 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CompoundMotionEvent : public ui::MotionEvent { 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit CompoundMotionEvent(MotionEventVector events) 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : events_(events.Pass()) { 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_GE(events_.size(), 1U); 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~CompoundMotionEvent() {} 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual int GetId() const OVERRIDE { return latest().GetId(); } 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual Action GetAction() const OVERRIDE { return latest().GetAction(); } 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual int GetActionIndex() const OVERRIDE { 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return latest().GetActionIndex(); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual size_t GetPointerCount() const OVERRIDE { 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return latest().GetPointerCount(); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual int GetPointerId(size_t pointer_index) const OVERRIDE { 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return latest().GetPointerId(pointer_index); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual float GetX(size_t pointer_index) const OVERRIDE { 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return latest().GetX(pointer_index); 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual float GetY(size_t pointer_index) const OVERRIDE { 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return latest().GetY(pointer_index); 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual float GetRawX(size_t pointer_index) const OVERRIDE { 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return latest().GetRawX(pointer_index); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual float GetRawY(size_t pointer_index) const OVERRIDE { 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return latest().GetRawY(pointer_index); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual float GetTouchMajor(size_t pointer_index) const OVERRIDE { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return latest().GetTouchMajor(pointer_index); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual float GetTouchMinor(size_t pointer_index) const OVERRIDE { 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return latest().GetTouchMinor(pointer_index); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual float GetOrientation(size_t pointer_index) const OVERRIDE { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return latest().GetOrientation(pointer_index); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual float GetPressure(size_t pointer_index) const OVERRIDE { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return latest().GetPressure(pointer_index); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ToolType GetToolType(size_t pointer_index) const OVERRIDE { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return latest().GetToolType(pointer_index); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetButtonState() const OVERRIDE { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return latest().GetButtonState(); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int GetFlags() const OVERRIDE { return latest().GetFlags(); } 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual base::TimeTicks GetEventTime() const OVERRIDE { 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return latest().GetEventTime(); 238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 239f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 240f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual size_t GetHistorySize() const OVERRIDE { return events_.size() - 1; } 241f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 242f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual base::TimeTicks GetHistoricalEventTime( 243f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t historical_index) const OVERRIDE { 244f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) DCHECK_LT(historical_index, GetHistorySize()); 245f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) return events_[historical_index]->GetEventTime(); 246f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 247f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 248f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) virtual float GetHistoricalTouchMajor( 249f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t pointer_index, 250f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) size_t historical_index) const OVERRIDE { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LT(historical_index, GetHistorySize()); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return events_[historical_index]->GetTouchMajor(); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual float GetHistoricalX(size_t pointer_index, 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t historical_index) const OVERRIDE { 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_LT(historical_index, GetHistorySize()); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return events_[historical_index]->GetX(pointer_index); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual float GetHistoricalY(size_t pointer_index, 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t historical_index) const OVERRIDE { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_LT(historical_index, GetHistorySize()); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return events_[historical_index]->GetY(pointer_index); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual scoped_ptr<MotionEvent> Clone() const OVERRIDE { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MotionEventVector cloned_events; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cloned_events.reserve(events_.size()); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < events_.size(); ++i) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cloned_events.push_back(events_[i]->Clone().release()); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return scoped_ptr<MotionEvent>( 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new CompoundMotionEvent(cloned_events.Pass())); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual scoped_ptr<MotionEvent> Cancel() const OVERRIDE { 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return latest().Cancel(); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the new, resampled event, or NULL if none was created. 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(jdduke): Revisit resampling to handle cases where alternating frames 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // are resampled or resampling is otherwise inconsistent, e.g., a 90hz input 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and 60hz frame signal could phase-align such that even frames yield an 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // extrapolated event and odd frames are not resampled, crbug.com/399381. 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MotionEvent* TryResample(base::TimeTicks resample_time, 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::MotionEvent* next) { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(GetAction(), ACTION_MOVE); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::MotionEvent* event0 = NULL; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const ui::MotionEvent* event1 = NULL; 29058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (next) { 29158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(resample_time < next->GetEventTime()); 29258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Interpolate between current sample and future sample. 29358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) event0 = events_.back(); 29458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) event1 = next; 29558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else if (events_.size() >= 2) { 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extrapolate future sample using current sample and past sample. 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event0 = events_[events_.size() - 2]; 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event1 = events_[events_.size() - 1]; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeTicks time1 = event1->GetEventTime(); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks max_predict = 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) time1 + 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::min((event1->GetEventTime() - event0->GetEventTime()) / 2, 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kResampleMaxPredictionMs)); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (resample_time > max_predict) { 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_INSTANT2("input", 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "MotionEventBuffer::TryResample prediction adjust", 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_SCOPE_THREAD, 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "original(ms)", 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (resample_time - time1).InMilliseconds(), 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "adjusted(ms)", 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (max_predict - time1).InMilliseconds()); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resample_time = max_predict; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_INSTANT0("input", 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "MotionEventBuffer::TryResample insufficient data", 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_SCOPE_THREAD); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 32258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(event0); 32358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(event1); 32458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const base::TimeTicks time0 = event0->GetEventTime(); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeTicks time1 = event1->GetEventTime(); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta delta = time1 - time0; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delta < base::TimeDelta::FromMilliseconds(kResampleMinDeltaMs)) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_INSTANT1("input", 32958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) "MotionEventBuffer::TryResample failure", 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TRACE_EVENT_SCOPE_THREAD, 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "event_delta_too_small(ms)", 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delta.InMilliseconds()); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) events_.push_back( 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ResampleMotionEvent(*event0, *event1, resample_time).release()); 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return events_.back(); 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t samples() const { return events_.size(); } 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const MotionEvent& latest() const { return *events_.back(); } 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Events are in order from oldest to newest. 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MotionEventVector events_; 3483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(CompoundMotionEvent); 3503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}; 3513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} // namespace 3533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)MotionEventBuffer::MotionEventBuffer(MotionEventBufferClient* client, 3553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) bool enable_resampling) 3563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : client_(client), resample_(enable_resampling) { 3573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)MotionEventBuffer::~MotionEventBuffer() { 3603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 3613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void MotionEventBuffer::OnMotionEvent(const MotionEvent& event) { 3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (event.GetAction() != MotionEvent::ACTION_MOVE) { 3643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) last_extrapolated_event_time_ = base::TimeTicks(); 3653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!buffered_events_.empty()) 3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FlushWithoutResampling(buffered_events_.Pass()); 3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) client_->ForwardMotionEvent(event); 3683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 3693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // Guard against events that are *older* than the last one that may have been 3723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // artificially synthesized. 3733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (!last_extrapolated_event_time_.is_null()) { 3743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) DCHECK(buffered_events_.empty()); 3753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (event.GetEventTime() < last_extrapolated_event_time_) 3763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 3773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) last_extrapolated_event_time_ = base::TimeTicks(); 3783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<MotionEvent> clone = event.Clone(); 3813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (buffered_events_.empty()) { 3823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) buffered_events_.push_back(clone.release()); 3833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) client_->SetNeedsFlush(); 3843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 3853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) if (CanAddSample(*buffered_events_.front(), *clone)) { 3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(buffered_events_.back()->GetEventTime() <= clone->GetEventTime()); 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FlushWithoutResampling(buffered_events_.Pass()); 3913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 3923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 3933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) buffered_events_.push_back(clone.release()); 3943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) // No need to request another flush as the first event will have requested it. 39558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 39658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 39758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void MotionEventBuffer::Flush(base::TimeTicks frame_time) { 39858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (buffered_events_.empty()) 39958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 40058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 40158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Shifting the sample time back slightly minimizes the potential for 40258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // misprediction when extrapolating events. 40358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (resample_) 40458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) frame_time -= base::TimeDelta::FromMilliseconds(kResampleLatencyMs); 40558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 40658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // TODO(jdduke): Use a persistent MotionEventVector vector for temporary 40758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // storage. 40858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) MotionEventVector events( 40958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ConsumeSamplesNoLaterThan(&buffered_events_, frame_time)); 41058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (events.empty()) { 41158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) DCHECK(!buffered_events_.empty()); 41258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) client_->SetNeedsFlush(); 41358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return; 41458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 41558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 41658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!resample_ || (events.size() == 1 && buffered_events_.empty())) { 41758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) FlushWithoutResampling(events.Pass()); 41858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!buffered_events_.empty()) 41958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) client_->SetNeedsFlush(); 4201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 42158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 42258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 42358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) CompoundMotionEvent resampled_event(events.Pass()); 42458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::TimeTicks original_event_time = resampled_event.GetEventTime(); 42558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const MotionEvent* next_event = 42658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) !buffered_events_.empty() ? buffered_events_.front() : NULL; 42758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 42858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Try to interpolate/extrapolate a new event at |frame_time|. Note that 42958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // |new_event|, if non-NULL, is owned by |resampled_event_|. 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MotionEvent* new_event = 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) resampled_event.TryResample(frame_time, next_event); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Log the extrapolated event time, guarding against subsequently queued 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // events that might have an earlier timestamp. 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!next_event && new_event && 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_event->GetEventTime() > original_event_time) { 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_extrapolated_event_time_ = new_event->GetEventTime(); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_extrapolated_event_time_ = base::TimeTicks(); 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_->ForwardMotionEvent(resampled_event); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!buffered_events_.empty()) 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_->SetNeedsFlush(); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 446eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void MotionEventBuffer::FlushWithoutResampling(MotionEventVector events) { 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_extrapolated_event_time_ = base::TimeTicks(); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (events.empty()) 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 45258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (events.size() == 1) { 45358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Avoid CompoundEvent creation to prevent unnecessary allocations. 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<MotionEvent> event(events.front()); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events.weak_clear(); 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_->ForwardMotionEvent(*event); 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CompoundMotionEvent compound_event(events.Pass()); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_->ForwardMotionEvent(compound_event); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ui 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)