Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(442)

Side by Side Diff: ui/events/gesture_detection/motion_event_buffer.cc

Issue 1539583003: Convert Pass()→std::move() in ui/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ui/events/event_utils.cc ('k') | ui/events/gesture_detection/motion_event_buffer_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <utility>
8
7 #include "base/trace_event/trace_event.h" 9 #include "base/trace_event/trace_event.h"
8 #include "ui/events/gesture_detection/motion_event_generic.h" 10 #include "ui/events/gesture_detection/motion_event_generic.h"
9 11
10 namespace ui { 12 namespace ui {
11 namespace { 13 namespace {
12 14
13 // Latency added during resampling. A few milliseconds doesn't hurt much but 15 // Latency added during resampling. A few milliseconds doesn't hurt much but
14 // reduces the impact of mispredicted touch positions. 16 // reduces the impact of mispredicted touch positions.
15 const int kResampleLatencyMs = 5; 17 const int kResampleLatencyMs = 5;
16 18
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 67
66 MotionEventVector ConsumeSamplesNoLaterThan(MotionEventVector* batch, 68 MotionEventVector ConsumeSamplesNoLaterThan(MotionEventVector* batch,
67 base::TimeTicks time) { 69 base::TimeTicks time) {
68 DCHECK(batch); 70 DCHECK(batch);
69 size_t count = CountSamplesNoLaterThan(*batch, time); 71 size_t count = CountSamplesNoLaterThan(*batch, time);
70 DCHECK_GE(batch->size(), count); 72 DCHECK_GE(batch->size(), count);
71 if (count == 0) 73 if (count == 0)
72 return MotionEventVector(); 74 return MotionEventVector();
73 75
74 if (count == batch->size()) 76 if (count == batch->size())
75 return batch->Pass(); 77 return std::move(*batch);
76 78
77 // TODO(jdduke): Use a ScopedDeque to work around this mess. 79 // TODO(jdduke): Use a ScopedDeque to work around this mess.
78 MotionEventVector unconsumed_batch; 80 MotionEventVector unconsumed_batch;
79 unconsumed_batch.insert( 81 unconsumed_batch.insert(
80 unconsumed_batch.begin(), batch->begin() + count, batch->end()); 82 unconsumed_batch.begin(), batch->begin() + count, batch->end());
81 batch->weak_erase(batch->begin() + count, batch->end()); 83 batch->weak_erase(batch->begin() + count, batch->end());
82 84
83 unconsumed_batch.swap(*batch); 85 unconsumed_batch.swap(*batch);
84 DCHECK_GE(unconsumed_batch.size(), 1U); 86 DCHECK_GE(unconsumed_batch.size(), 1U);
85 return unconsumed_batch.Pass(); 87 return unconsumed_batch;
86 } 88 }
87 89
88 // Linearly interpolate the pointer position between two MotionEvent samples. 90 // Linearly interpolate the pointer position between two MotionEvent samples.
89 // Only pointers of finger or unknown type will be resampled. 91 // Only pointers of finger or unknown type will be resampled.
90 PointerProperties ResamplePointer(const MotionEvent& event0, 92 PointerProperties ResamplePointer(const MotionEvent& event0,
91 const MotionEvent& event1, 93 const MotionEvent& event1,
92 size_t event0_pointer_index, 94 size_t event0_pointer_index,
93 size_t event1_pointer_index, 95 size_t event1_pointer_index,
94 float alpha) { 96 float alpha) {
95 DCHECK_EQ(event0.GetPointerId(event0_pointer_index), 97 DCHECK_EQ(event0.GetPointerId(event0_pointer_index),
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 if (event0_i == 0) { 142 if (event0_i == 0) {
141 event.reset(new MotionEventGeneric( 143 event.reset(new MotionEventGeneric(
142 MotionEvent::ACTION_MOVE, resample_time, pointer)); 144 MotionEvent::ACTION_MOVE, resample_time, pointer));
143 } else { 145 } else {
144 event->PushPointer(pointer); 146 event->PushPointer(pointer);
145 } 147 }
146 } 148 }
147 149
148 DCHECK(event); 150 DCHECK(event);
149 event->set_button_state(event0.GetButtonState()); 151 event->set_button_state(event0.GetButtonState());
150 return event.Pass(); 152 return event;
151 } 153 }
152 154
153 // Synthesize a compound MotionEventGeneric event from a sequence of events. 155 // Synthesize a compound MotionEventGeneric event from a sequence of events.
154 // Events must be in non-decreasing (time) order. 156 // Events must be in non-decreasing (time) order.
155 scoped_ptr<MotionEventGeneric> ConsumeSamples(MotionEventVector events) { 157 scoped_ptr<MotionEventGeneric> ConsumeSamples(MotionEventVector events) {
156 DCHECK(!events.empty()); 158 DCHECK(!events.empty());
157 scoped_ptr<MotionEventGeneric> event(events.back()); 159 scoped_ptr<MotionEventGeneric> event(events.back());
158 for (size_t i = 0; i + 1 < events.size(); ++i) 160 for (size_t i = 0; i + 1 < events.size(); ++i)
159 event->PushHistoricalEvent(scoped_ptr<MotionEvent>(events[i])); 161 event->PushHistoricalEvent(scoped_ptr<MotionEvent>(events[i]));
160 events.weak_clear(); 162 events.weak_clear();
161 return event.Pass(); 163 return event;
162 } 164 }
163 165
164 // Consume a series of event samples, attempting to synthesize a new, synthetic 166 // Consume a series of event samples, attempting to synthesize a new, synthetic
165 // event if the samples and sample time meet certain interpolation/extrapolation 167 // event if the samples and sample time meet certain interpolation/extrapolation
166 // conditions. If such conditions are met, the provided samples will be added 168 // conditions. If such conditions are met, the provided samples will be added
167 // to the synthetic event's history, otherwise, the samples will be used to 169 // to the synthetic event's history, otherwise, the samples will be used to
168 // generate a basic, compound event. 170 // generate a basic, compound event.
169 // TODO(jdduke): Revisit resampling to handle cases where alternating frames 171 // TODO(jdduke): Revisit resampling to handle cases where alternating frames
170 // are resampled or resampling is otherwise inconsistent, e.g., a 90hz input 172 // are resampled or resampling is otherwise inconsistent, e.g., a 90hz input
171 // and 60hz frame signal could phase-align such that even frames yield an 173 // and 60hz frame signal could phase-align such that even frames yield an
(...skipping 26 matching lines...) Expand all
198 "original(ms)", 200 "original(ms)",
199 (resample_time - time1).InMilliseconds(), 201 (resample_time - time1).InMilliseconds(),
200 "adjusted(ms)", 202 "adjusted(ms)",
201 (max_predict - time1).InMilliseconds()); 203 (max_predict - time1).InMilliseconds());
202 resample_time = max_predict; 204 resample_time = max_predict;
203 } 205 }
204 } else { 206 } else {
205 TRACE_EVENT_INSTANT0("input", 207 TRACE_EVENT_INSTANT0("input",
206 "MotionEventBuffer::TryResample insufficient data", 208 "MotionEventBuffer::TryResample insufficient data",
207 TRACE_EVENT_SCOPE_THREAD); 209 TRACE_EVENT_SCOPE_THREAD);
208 return ConsumeSamples(events.Pass()); 210 return ConsumeSamples(std::move(events));
209 } 211 }
210 212
211 DCHECK(event0); 213 DCHECK(event0);
212 DCHECK(event1); 214 DCHECK(event1);
213 const base::TimeTicks time0 = event0->GetEventTime(); 215 const base::TimeTicks time0 = event0->GetEventTime();
214 const base::TimeTicks time1 = event1->GetEventTime(); 216 const base::TimeTicks time1 = event1->GetEventTime();
215 base::TimeDelta delta = time1 - time0; 217 base::TimeDelta delta = time1 - time0;
216 if (delta < base::TimeDelta::FromMilliseconds(kResampleMinDeltaMs)) { 218 if (delta < base::TimeDelta::FromMilliseconds(kResampleMinDeltaMs)) {
217 TRACE_EVENT_INSTANT1("input", 219 TRACE_EVENT_INSTANT1("input",
218 "MotionEventBuffer::TryResample failure", 220 "MotionEventBuffer::TryResample failure",
219 TRACE_EVENT_SCOPE_THREAD, 221 TRACE_EVENT_SCOPE_THREAD,
220 "event_delta_too_small(ms)", 222 "event_delta_too_small(ms)",
221 delta.InMilliseconds()); 223 delta.InMilliseconds());
222 return ConsumeSamples(events.Pass()); 224 return ConsumeSamples(std::move(events));
223 } 225 }
224 226
225 scoped_ptr<MotionEventGeneric> resampled_event = 227 scoped_ptr<MotionEventGeneric> resampled_event =
226 ResampleMotionEvent(*event0, *event1, resample_time); 228 ResampleMotionEvent(*event0, *event1, resample_time);
227 for (size_t i = 0; i < events.size(); ++i) 229 for (size_t i = 0; i < events.size(); ++i)
228 resampled_event->PushHistoricalEvent(scoped_ptr<MotionEvent>(events[i])); 230 resampled_event->PushHistoricalEvent(scoped_ptr<MotionEvent>(events[i]));
229 events.weak_clear(); 231 events.weak_clear();
230 return resampled_event.Pass(); 232 return resampled_event;
231 } 233 }
232 234
233 } // namespace 235 } // namespace
234 236
235 MotionEventBuffer::MotionEventBuffer(MotionEventBufferClient* client, 237 MotionEventBuffer::MotionEventBuffer(MotionEventBufferClient* client,
236 bool enable_resampling) 238 bool enable_resampling)
237 : client_(client), resample_(enable_resampling) { 239 : client_(client), resample_(enable_resampling) {
238 } 240 }
239 241
240 MotionEventBuffer::~MotionEventBuffer() { 242 MotionEventBuffer::~MotionEventBuffer() {
241 } 243 }
242 244
243 void MotionEventBuffer::OnMotionEvent(const MotionEvent& event) { 245 void MotionEventBuffer::OnMotionEvent(const MotionEvent& event) {
244 DCHECK_EQ(0U, event.GetHistorySize()); 246 DCHECK_EQ(0U, event.GetHistorySize());
245 if (event.GetAction() != MotionEvent::ACTION_MOVE) { 247 if (event.GetAction() != MotionEvent::ACTION_MOVE) {
246 last_extrapolated_event_time_ = base::TimeTicks(); 248 last_extrapolated_event_time_ = base::TimeTicks();
247 if (!buffered_events_.empty()) 249 if (!buffered_events_.empty())
248 FlushWithoutResampling(buffered_events_.Pass()); 250 FlushWithoutResampling(std::move(buffered_events_));
249 client_->ForwardMotionEvent(event); 251 client_->ForwardMotionEvent(event);
250 return; 252 return;
251 } 253 }
252 254
253 // Guard against events that are *older* than the last one that may have been 255 // Guard against events that are *older* than the last one that may have been
254 // artificially synthesized. 256 // artificially synthesized.
255 if (!last_extrapolated_event_time_.is_null()) { 257 if (!last_extrapolated_event_time_.is_null()) {
256 DCHECK(buffered_events_.empty()); 258 DCHECK(buffered_events_.empty());
257 if (event.GetEventTime() < last_extrapolated_event_time_) 259 if (event.GetEventTime() < last_extrapolated_event_time_)
258 return; 260 return;
259 last_extrapolated_event_time_ = base::TimeTicks(); 261 last_extrapolated_event_time_ = base::TimeTicks();
260 } 262 }
261 263
262 scoped_ptr<MotionEventGeneric> clone = MotionEventGeneric::CloneEvent(event); 264 scoped_ptr<MotionEventGeneric> clone = MotionEventGeneric::CloneEvent(event);
263 if (buffered_events_.empty()) { 265 if (buffered_events_.empty()) {
264 buffered_events_.push_back(clone.Pass()); 266 buffered_events_.push_back(std::move(clone));
265 client_->SetNeedsFlush(); 267 client_->SetNeedsFlush();
266 return; 268 return;
267 } 269 }
268 270
269 if (CanAddSample(*buffered_events_.front(), *clone)) { 271 if (CanAddSample(*buffered_events_.front(), *clone)) {
270 DCHECK(buffered_events_.back()->GetEventTime() <= clone->GetEventTime()); 272 DCHECK(buffered_events_.back()->GetEventTime() <= clone->GetEventTime());
271 } else { 273 } else {
272 FlushWithoutResampling(buffered_events_.Pass()); 274 FlushWithoutResampling(std::move(buffered_events_));
273 } 275 }
274 276
275 buffered_events_.push_back(clone.Pass()); 277 buffered_events_.push_back(std::move(clone));
276 // No need to request another flush as the first event will have requested it. 278 // No need to request another flush as the first event will have requested it.
277 } 279 }
278 280
279 void MotionEventBuffer::Flush(base::TimeTicks frame_time) { 281 void MotionEventBuffer::Flush(base::TimeTicks frame_time) {
280 if (buffered_events_.empty()) 282 if (buffered_events_.empty())
281 return; 283 return;
282 284
283 // Shifting the sample time back slightly minimizes the potential for 285 // Shifting the sample time back slightly minimizes the potential for
284 // misprediction when extrapolating events. 286 // misprediction when extrapolating events.
285 if (resample_) 287 if (resample_)
286 frame_time -= base::TimeDelta::FromMilliseconds(kResampleLatencyMs); 288 frame_time -= base::TimeDelta::FromMilliseconds(kResampleLatencyMs);
287 289
288 // TODO(jdduke): Use a persistent MotionEventVector vector for temporary 290 // TODO(jdduke): Use a persistent MotionEventVector vector for temporary
289 // storage. 291 // storage.
290 MotionEventVector events( 292 MotionEventVector events(
291 ConsumeSamplesNoLaterThan(&buffered_events_, frame_time)); 293 ConsumeSamplesNoLaterThan(&buffered_events_, frame_time));
292 if (events.empty()) { 294 if (events.empty()) {
293 DCHECK(!buffered_events_.empty()); 295 DCHECK(!buffered_events_.empty());
294 client_->SetNeedsFlush(); 296 client_->SetNeedsFlush();
295 return; 297 return;
296 } 298 }
297 299
298 if (!resample_ || (events.size() == 1 && buffered_events_.empty())) { 300 if (!resample_ || (events.size() == 1 && buffered_events_.empty())) {
299 FlushWithoutResampling(events.Pass()); 301 FlushWithoutResampling(std::move(events));
300 if (!buffered_events_.empty()) 302 if (!buffered_events_.empty())
301 client_->SetNeedsFlush(); 303 client_->SetNeedsFlush();
302 return; 304 return;
303 } 305 }
304 306
305 FlushWithResampling(events.Pass(), frame_time); 307 FlushWithResampling(std::move(events), frame_time);
306 } 308 }
307 309
308 void MotionEventBuffer::FlushWithResampling(MotionEventVector events, 310 void MotionEventBuffer::FlushWithResampling(MotionEventVector events,
309 base::TimeTicks resample_time) { 311 base::TimeTicks resample_time) {
310 DCHECK(!events.empty()); 312 DCHECK(!events.empty());
311 base::TimeTicks original_event_time = events.back()->GetEventTime(); 313 base::TimeTicks original_event_time = events.back()->GetEventTime();
312 const MotionEvent* next_event = 314 const MotionEvent* next_event =
313 !buffered_events_.empty() ? buffered_events_.front() : nullptr; 315 !buffered_events_.empty() ? buffered_events_.front() : nullptr;
314 316
315 scoped_ptr<MotionEventGeneric> resampled_event = 317 scoped_ptr<MotionEventGeneric> resampled_event =
316 ConsumeSamplesAndTryResampling(resample_time, events.Pass(), next_event); 318 ConsumeSamplesAndTryResampling(resample_time, std::move(events),
319 next_event);
317 DCHECK(resampled_event); 320 DCHECK(resampled_event);
318 321
319 // Log the extrapolated event time, guarding against subsequently queued 322 // Log the extrapolated event time, guarding against subsequently queued
320 // events that might have an earlier timestamp. 323 // events that might have an earlier timestamp.
321 if (!next_event && resampled_event->GetEventTime() > original_event_time) { 324 if (!next_event && resampled_event->GetEventTime() > original_event_time) {
322 last_extrapolated_event_time_ = resampled_event->GetEventTime(); 325 last_extrapolated_event_time_ = resampled_event->GetEventTime();
323 } else { 326 } else {
324 last_extrapolated_event_time_ = base::TimeTicks(); 327 last_extrapolated_event_time_ = base::TimeTicks();
325 } 328 }
326 329
327 client_->ForwardMotionEvent(*resampled_event); 330 client_->ForwardMotionEvent(*resampled_event);
328 if (!buffered_events_.empty()) 331 if (!buffered_events_.empty())
329 client_->SetNeedsFlush(); 332 client_->SetNeedsFlush();
330 } 333 }
331 334
332 void MotionEventBuffer::FlushWithoutResampling(MotionEventVector events) { 335 void MotionEventBuffer::FlushWithoutResampling(MotionEventVector events) {
333 last_extrapolated_event_time_ = base::TimeTicks(); 336 last_extrapolated_event_time_ = base::TimeTicks();
334 if (events.empty()) 337 if (events.empty())
335 return; 338 return;
336 339
337 client_->ForwardMotionEvent(*ConsumeSamples(events.Pass())); 340 client_->ForwardMotionEvent(*ConsumeSamples(std::move(events)));
338 } 341 }
339 342
340 } // namespace ui 343 } // namespace ui
OLDNEW
« no previous file with comments | « ui/events/event_utils.cc ('k') | ui/events/gesture_detection/motion_event_buffer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698