| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/events/gesture_detection/motion_event_buffer.h" | 5 #include "ui/events/gesture_detection/motion_event_buffer.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 110 PointerProperties p(event0, event0_pointer_index); | 110 PointerProperties p(event0, event0_pointer_index); |
| 111 p.x = Lerp(p.x, event1.GetX(event1_pointer_index), alpha); | 111 p.x = Lerp(p.x, event1.GetX(event1_pointer_index), alpha); |
| 112 p.y = Lerp(p.y, event1.GetY(event1_pointer_index), alpha); | 112 p.y = Lerp(p.y, event1.GetY(event1_pointer_index), alpha); |
| 113 p.raw_x = Lerp(p.raw_x, event1.GetRawX(event1_pointer_index), alpha); | 113 p.raw_x = Lerp(p.raw_x, event1.GetRawX(event1_pointer_index), alpha); |
| 114 p.raw_y = Lerp(p.raw_y, event1.GetRawY(event1_pointer_index), alpha); | 114 p.raw_y = Lerp(p.raw_y, event1.GetRawY(event1_pointer_index), alpha); |
| 115 return p; | 115 return p; |
| 116 } | 116 } |
| 117 | 117 |
| 118 // Linearly interpolate the pointers between two event samples using the | 118 // Linearly interpolate the pointers between two event samples using the |
| 119 // provided |resample_time|. | 119 // provided |resample_time|. |
| 120 scoped_ptr<MotionEventGeneric> ResampleMotionEvent( | 120 std::unique_ptr<MotionEventGeneric> ResampleMotionEvent( |
| 121 const MotionEvent& event0, | 121 const MotionEvent& event0, |
| 122 const MotionEvent& event1, | 122 const MotionEvent& event1, |
| 123 base::TimeTicks resample_time) { | 123 base::TimeTicks resample_time) { |
| 124 DCHECK_EQ(MotionEvent::ACTION_MOVE, event0.GetAction()); | 124 DCHECK_EQ(MotionEvent::ACTION_MOVE, event0.GetAction()); |
| 125 DCHECK_EQ(event0.GetPointerCount(), event1.GetPointerCount()); | 125 DCHECK_EQ(event0.GetPointerCount(), event1.GetPointerCount()); |
| 126 | 126 |
| 127 const base::TimeTicks time0 = event0.GetEventTime(); | 127 const base::TimeTicks time0 = event0.GetEventTime(); |
| 128 const base::TimeTicks time1 = event1.GetEventTime(); | 128 const base::TimeTicks time1 = event1.GetEventTime(); |
| 129 DCHECK(time0 < time1); | 129 DCHECK(time0 < time1); |
| 130 DCHECK(time0 <= resample_time); | 130 DCHECK(time0 <= resample_time); |
| 131 | 131 |
| 132 const float alpha = (resample_time - time0).InMillisecondsF() / | 132 const float alpha = (resample_time - time0).InMillisecondsF() / |
| 133 (time1 - time0).InMillisecondsF(); | 133 (time1 - time0).InMillisecondsF(); |
| 134 | 134 |
| 135 scoped_ptr<MotionEventGeneric> event; | 135 std::unique_ptr<MotionEventGeneric> event; |
| 136 const size_t pointer_count = event0.GetPointerCount(); | 136 const size_t pointer_count = event0.GetPointerCount(); |
| 137 DCHECK_EQ(pointer_count, event1.GetPointerCount()); | 137 DCHECK_EQ(pointer_count, event1.GetPointerCount()); |
| 138 for (size_t event0_i = 0; event0_i < pointer_count; ++event0_i) { | 138 for (size_t event0_i = 0; event0_i < pointer_count; ++event0_i) { |
| 139 int event1_i = event1.FindPointerIndexOfId(event0.GetPointerId(event0_i)); | 139 int event1_i = event1.FindPointerIndexOfId(event0.GetPointerId(event0_i)); |
| 140 DCHECK_NE(event1_i, -1); | 140 DCHECK_NE(event1_i, -1); |
| 141 PointerProperties pointer = ResamplePointer( | 141 PointerProperties pointer = ResamplePointer( |
| 142 event0, event1, event0_i, static_cast<size_t>(event1_i), alpha); | 142 event0, event1, event0_i, static_cast<size_t>(event1_i), alpha); |
| 143 | 143 |
| 144 if (event0_i == 0) { | 144 if (event0_i == 0) { |
| 145 event.reset(new MotionEventGeneric( | 145 event.reset(new MotionEventGeneric( |
| 146 MotionEvent::ACTION_MOVE, resample_time, pointer)); | 146 MotionEvent::ACTION_MOVE, resample_time, pointer)); |
| 147 } else { | 147 } else { |
| 148 event->PushPointer(pointer); | 148 event->PushPointer(pointer); |
| 149 } | 149 } |
| 150 } | 150 } |
| 151 | 151 |
| 152 DCHECK(event); | 152 DCHECK(event); |
| 153 event->set_button_state(event0.GetButtonState()); | 153 event->set_button_state(event0.GetButtonState()); |
| 154 return event; | 154 return event; |
| 155 } | 155 } |
| 156 | 156 |
| 157 // Synthesize a compound MotionEventGeneric event from a sequence of events. | 157 // Synthesize a compound MotionEventGeneric event from a sequence of events. |
| 158 // Events must be in non-decreasing (time) order. | 158 // Events must be in non-decreasing (time) order. |
| 159 scoped_ptr<MotionEventGeneric> ConsumeSamples(MotionEventVector events) { | 159 std::unique_ptr<MotionEventGeneric> ConsumeSamples(MotionEventVector events) { |
| 160 DCHECK(!events.empty()); | 160 DCHECK(!events.empty()); |
| 161 scoped_ptr<MotionEventGeneric> event(events.back()); | 161 std::unique_ptr<MotionEventGeneric> event(events.back()); |
| 162 for (size_t i = 0; i + 1 < events.size(); ++i) | 162 for (size_t i = 0; i + 1 < events.size(); ++i) |
| 163 event->PushHistoricalEvent(scoped_ptr<MotionEvent>(events[i])); | 163 event->PushHistoricalEvent(std::unique_ptr<MotionEvent>(events[i])); |
| 164 events.weak_clear(); | 164 events.weak_clear(); |
| 165 return event; | 165 return event; |
| 166 } | 166 } |
| 167 | 167 |
| 168 // Consume a series of event samples, attempting to synthesize a new, synthetic | 168 // Consume a series of event samples, attempting to synthesize a new, synthetic |
| 169 // event if the samples and sample time meet certain interpolation/extrapolation | 169 // event if the samples and sample time meet certain interpolation/extrapolation |
| 170 // conditions. If such conditions are met, the provided samples will be added | 170 // conditions. If such conditions are met, the provided samples will be added |
| 171 // to the synthetic event's history, otherwise, the samples will be used to | 171 // to the synthetic event's history, otherwise, the samples will be used to |
| 172 // generate a basic, compound event. | 172 // generate a basic, compound event. |
| 173 // TODO(jdduke): Revisit resampling to handle cases where alternating frames | 173 // TODO(jdduke): Revisit resampling to handle cases where alternating frames |
| 174 // are resampled or resampling is otherwise inconsistent, e.g., a 90hz input | 174 // are resampled or resampling is otherwise inconsistent, e.g., a 90hz input |
| 175 // and 60hz frame signal could phase-align such that even frames yield an | 175 // and 60hz frame signal could phase-align such that even frames yield an |
| 176 // extrapolated event and odd frames are not resampled, crbug.com/399381. | 176 // extrapolated event and odd frames are not resampled, crbug.com/399381. |
| 177 scoped_ptr<MotionEventGeneric> ConsumeSamplesAndTryResampling( | 177 std::unique_ptr<MotionEventGeneric> ConsumeSamplesAndTryResampling( |
| 178 base::TimeTicks resample_time, | 178 base::TimeTicks resample_time, |
| 179 MotionEventVector events, | 179 MotionEventVector events, |
| 180 const MotionEvent* next) { | 180 const MotionEvent* next) { |
| 181 const ui::MotionEvent* event0 = nullptr; | 181 const ui::MotionEvent* event0 = nullptr; |
| 182 const ui::MotionEvent* event1 = nullptr; | 182 const ui::MotionEvent* event1 = nullptr; |
| 183 if (next) { | 183 if (next) { |
| 184 DCHECK(resample_time < next->GetEventTime()); | 184 DCHECK(resample_time < next->GetEventTime()); |
| 185 // Interpolate between current sample and future sample. | 185 // Interpolate between current sample and future sample. |
| 186 event0 = events.back(); | 186 event0 = events.back(); |
| 187 event1 = next; | 187 event1 = next; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 base::TimeDelta delta = time1 - time0; | 219 base::TimeDelta delta = time1 - time0; |
| 220 if (delta < base::TimeDelta::FromMilliseconds(kResampleMinDeltaMs)) { | 220 if (delta < base::TimeDelta::FromMilliseconds(kResampleMinDeltaMs)) { |
| 221 TRACE_EVENT_INSTANT1("input", | 221 TRACE_EVENT_INSTANT1("input", |
| 222 "MotionEventBuffer::TryResample failure", | 222 "MotionEventBuffer::TryResample failure", |
| 223 TRACE_EVENT_SCOPE_THREAD, | 223 TRACE_EVENT_SCOPE_THREAD, |
| 224 "event_delta_too_small(ms)", | 224 "event_delta_too_small(ms)", |
| 225 delta.InMilliseconds()); | 225 delta.InMilliseconds()); |
| 226 return ConsumeSamples(std::move(events)); | 226 return ConsumeSamples(std::move(events)); |
| 227 } | 227 } |
| 228 | 228 |
| 229 scoped_ptr<MotionEventGeneric> resampled_event = | 229 std::unique_ptr<MotionEventGeneric> resampled_event = |
| 230 ResampleMotionEvent(*event0, *event1, resample_time); | 230 ResampleMotionEvent(*event0, *event1, resample_time); |
| 231 for (size_t i = 0; i < events.size(); ++i) | 231 for (size_t i = 0; i < events.size(); ++i) |
| 232 resampled_event->PushHistoricalEvent(scoped_ptr<MotionEvent>(events[i])); | 232 resampled_event->PushHistoricalEvent( |
| 233 std::unique_ptr<MotionEvent>(events[i])); |
| 233 events.weak_clear(); | 234 events.weak_clear(); |
| 234 return resampled_event; | 235 return resampled_event; |
| 235 } | 236 } |
| 236 | 237 |
| 237 } // namespace | 238 } // namespace |
| 238 | 239 |
| 239 MotionEventBuffer::MotionEventBuffer(MotionEventBufferClient* client, | 240 MotionEventBuffer::MotionEventBuffer(MotionEventBufferClient* client, |
| 240 bool enable_resampling) | 241 bool enable_resampling) |
| 241 : client_(client), resample_(enable_resampling) { | 242 : client_(client), resample_(enable_resampling) { |
| 242 } | 243 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 256 | 257 |
| 257 // Guard against events that are *older* than the last one that may have been | 258 // Guard against events that are *older* than the last one that may have been |
| 258 // artificially synthesized. | 259 // artificially synthesized. |
| 259 if (!last_extrapolated_event_time_.is_null()) { | 260 if (!last_extrapolated_event_time_.is_null()) { |
| 260 DCHECK(buffered_events_.empty()); | 261 DCHECK(buffered_events_.empty()); |
| 261 if (event.GetEventTime() < last_extrapolated_event_time_) | 262 if (event.GetEventTime() < last_extrapolated_event_time_) |
| 262 return; | 263 return; |
| 263 last_extrapolated_event_time_ = base::TimeTicks(); | 264 last_extrapolated_event_time_ = base::TimeTicks(); |
| 264 } | 265 } |
| 265 | 266 |
| 266 scoped_ptr<MotionEventGeneric> clone = MotionEventGeneric::CloneEvent(event); | 267 std::unique_ptr<MotionEventGeneric> clone = |
| 268 MotionEventGeneric::CloneEvent(event); |
| 267 if (buffered_events_.empty()) { | 269 if (buffered_events_.empty()) { |
| 268 buffered_events_.push_back(std::move(clone)); | 270 buffered_events_.push_back(std::move(clone)); |
| 269 client_->SetNeedsFlush(); | 271 client_->SetNeedsFlush(); |
| 270 return; | 272 return; |
| 271 } | 273 } |
| 272 | 274 |
| 273 if (CanAddSample(*buffered_events_.front(), *clone)) { | 275 if (CanAddSample(*buffered_events_.front(), *clone)) { |
| 274 DCHECK(buffered_events_.back()->GetEventTime() <= clone->GetEventTime()); | 276 DCHECK(buffered_events_.back()->GetEventTime() <= clone->GetEventTime()); |
| 275 } else { | 277 } else { |
| 276 FlushWithoutResampling(std::move(buffered_events_)); | 278 FlushWithoutResampling(std::move(buffered_events_)); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 FlushWithResampling(std::move(events), frame_time); | 311 FlushWithResampling(std::move(events), frame_time); |
| 310 } | 312 } |
| 311 | 313 |
| 312 void MotionEventBuffer::FlushWithResampling(MotionEventVector events, | 314 void MotionEventBuffer::FlushWithResampling(MotionEventVector events, |
| 313 base::TimeTicks resample_time) { | 315 base::TimeTicks resample_time) { |
| 314 DCHECK(!events.empty()); | 316 DCHECK(!events.empty()); |
| 315 base::TimeTicks original_event_time = events.back()->GetEventTime(); | 317 base::TimeTicks original_event_time = events.back()->GetEventTime(); |
| 316 const MotionEvent* next_event = | 318 const MotionEvent* next_event = |
| 317 !buffered_events_.empty() ? buffered_events_.front() : nullptr; | 319 !buffered_events_.empty() ? buffered_events_.front() : nullptr; |
| 318 | 320 |
| 319 scoped_ptr<MotionEventGeneric> resampled_event = | 321 std::unique_ptr<MotionEventGeneric> resampled_event = |
| 320 ConsumeSamplesAndTryResampling(resample_time, std::move(events), | 322 ConsumeSamplesAndTryResampling(resample_time, std::move(events), |
| 321 next_event); | 323 next_event); |
| 322 DCHECK(resampled_event); | 324 DCHECK(resampled_event); |
| 323 | 325 |
| 324 // Log the extrapolated event time, guarding against subsequently queued | 326 // Log the extrapolated event time, guarding against subsequently queued |
| 325 // events that might have an earlier timestamp. | 327 // events that might have an earlier timestamp. |
| 326 if (!next_event && resampled_event->GetEventTime() > original_event_time) { | 328 if (!next_event && resampled_event->GetEventTime() > original_event_time) { |
| 327 last_extrapolated_event_time_ = resampled_event->GetEventTime(); | 329 last_extrapolated_event_time_ = resampled_event->GetEventTime(); |
| 328 } else { | 330 } else { |
| 329 last_extrapolated_event_time_ = base::TimeTicks(); | 331 last_extrapolated_event_time_ = base::TimeTicks(); |
| 330 } | 332 } |
| 331 | 333 |
| 332 client_->ForwardMotionEvent(*resampled_event); | 334 client_->ForwardMotionEvent(*resampled_event); |
| 333 if (!buffered_events_.empty()) | 335 if (!buffered_events_.empty()) |
| 334 client_->SetNeedsFlush(); | 336 client_->SetNeedsFlush(); |
| 335 } | 337 } |
| 336 | 338 |
| 337 void MotionEventBuffer::FlushWithoutResampling(MotionEventVector events) { | 339 void MotionEventBuffer::FlushWithoutResampling(MotionEventVector events) { |
| 338 last_extrapolated_event_time_ = base::TimeTicks(); | 340 last_extrapolated_event_time_ = base::TimeTicks(); |
| 339 if (events.empty()) | 341 if (events.empty()) |
| 340 return; | 342 return; |
| 341 | 343 |
| 342 client_->ForwardMotionEvent(*ConsumeSamples(std::move(events))); | 344 client_->ForwardMotionEvent(*ConsumeSamples(std::move(events))); |
| 343 } | 345 } |
| 344 | 346 |
| 345 } // namespace ui | 347 } // namespace ui |
| OLD | NEW |