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

Side by Side Diff: content/browser/renderer_host/input/gesture_event_queue.cc

Issue 2552853002: [Compositor event queue] Coalesce gesture scroll&pinch of the same sequence (Closed)
Patch Set: sadrul's comments, fix dependency Created 4 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 | « content/browser/renderer_host/input/gesture_event_queue.h ('k') | ui/events/blink/BUILD.gn » ('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 "content/browser/renderer_host/input/gesture_event_queue.h" 5 #include "content/browser/renderer_host/input/gesture_event_queue.h"
6 6
7 #include "base/trace_event/trace_event.h" 7 #include "base/trace_event/trace_event.h"
8 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controlle r.h" 8 #include "content/browser/renderer_host/input/touchpad_tap_suppression_controlle r.h"
9 #include "content/browser/renderer_host/input/touchscreen_tap_suppression_contro ller.h" 9 #include "content/browser/renderer_host/input/touchscreen_tap_suppression_contro ller.h"
10 #include "ui/events/blink/web_input_event_traits.h" 10 #include "ui/events/blink/web_input_event_traits.h"
11 11
12 using blink::WebGestureEvent; 12 using blink::WebGestureEvent;
13 using blink::WebInputEvent; 13 using blink::WebInputEvent;
14 14
15 namespace content { 15 namespace content {
16 namespace {
17
18 // Whether |event_in_queue| is GesturePinchUpdate or GestureScrollUpdate and
19 // has the same modifiers/source as the new scroll/pinch event. Compatible
20 // scroll and pinch event pairs can be logically coalesced.
21 bool IsCompatibleScrollorPinch(
22 const GestureEventWithLatencyInfo& new_event,
23 const GestureEventWithLatencyInfo& event_in_queue) {
24 DCHECK(new_event.event.type == WebInputEvent::GestureScrollUpdate ||
25 new_event.event.type == WebInputEvent::GesturePinchUpdate)
26 << "Invalid event type for pinch/scroll coalescing: "
27 << WebInputEvent::GetName(new_event.event.type);
28 DLOG_IF(WARNING, new_event.event.timeStampSeconds <
29 event_in_queue.event.timeStampSeconds)
30 << "Event time not monotonic?\n";
31 return (event_in_queue.event.type == WebInputEvent::GestureScrollUpdate ||
32 event_in_queue.event.type == WebInputEvent::GesturePinchUpdate) &&
33 event_in_queue.event.modifiers == new_event.event.modifiers &&
34 event_in_queue.event.sourceDevice == new_event.event.sourceDevice;
35 }
36
37 // Returns the transform matrix corresponding to the gesture event.
38 gfx::Transform GetTransformForEvent(
39 const GestureEventWithLatencyInfo& gesture_event) {
40 gfx::Transform gesture_transform;
41 if (gesture_event.event.type == WebInputEvent::GestureScrollUpdate) {
42 gesture_transform.Translate(gesture_event.event.data.scrollUpdate.deltaX,
43 gesture_event.event.data.scrollUpdate.deltaY);
44 } else if (gesture_event.event.type == WebInputEvent::GesturePinchUpdate) {
45 float scale = gesture_event.event.data.pinchUpdate.scale;
46 gesture_transform.Translate(-gesture_event.event.x, -gesture_event.event.y);
47 gesture_transform.Scale(scale, scale);
48 gesture_transform.Translate(gesture_event.event.x, gesture_event.event.y);
49 } else {
50 NOTREACHED() << "Invalid event type for transform retrieval: "
51 << WebInputEvent::GetName(gesture_event.event.type);
52 }
53 return gesture_transform;
54 }
55
56 } // namespace
57 16
58 GestureEventQueue::Config::Config() { 17 GestureEventQueue::Config::Config() {
59 } 18 }
60 19
61 GestureEventQueue::GestureEventQueue( 20 GestureEventQueue::GestureEventQueue(
62 GestureEventQueueClient* client, 21 GestureEventQueueClient* client,
63 TouchpadTapSuppressionControllerClient* touchpad_client, 22 TouchpadTapSuppressionControllerClient* touchpad_client,
64 const Config& config) 23 const Config& config)
65 : client_(client), 24 : client_(client),
66 fling_in_progress_(false), 25 fling_in_progress_(false),
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 if (coalesced_gesture_events_.size() == 1) { 284 if (coalesced_gesture_events_.size() == 1) {
326 client_->SendGestureEventImmediately(gesture_event); 285 client_->SendGestureEventImmediately(gesture_event);
327 } else if (coalesced_gesture_events_.size() == 2) { 286 } else if (coalesced_gesture_events_.size() == 2) {
328 DCHECK(!ignore_next_ack_); 287 DCHECK(!ignore_next_ack_);
329 // If there is an in-flight scroll, the new pinch can be forwarded 288 // If there is an in-flight scroll, the new pinch can be forwarded
330 // immediately, avoiding a potential frame delay between the two 289 // immediately, avoiding a potential frame delay between the two
331 // (similarly for an in-flight pinch with a new scroll). 290 // (similarly for an in-flight pinch with a new scroll).
332 const GestureEventWithLatencyInfo& first_event = 291 const GestureEventWithLatencyInfo& first_event =
333 coalesced_gesture_events_.front(); 292 coalesced_gesture_events_.front();
334 if (gesture_event.event.type != first_event.event.type && 293 if (gesture_event.event.type != first_event.event.type &&
335 IsCompatibleScrollorPinch(gesture_event, first_event)) { 294 ui::IsCompatibleScrollorPinch(gesture_event.event,
295 first_event.event)) {
336 ignore_next_ack_ = true; 296 ignore_next_ack_ = true;
337 client_->SendGestureEventImmediately(gesture_event); 297 client_->SendGestureEventImmediately(gesture_event);
338 } 298 }
339 } 299 }
340 return; 300 return;
341 } 301 }
342 302
343 GestureEventWithLatencyInfo* last_event = &coalesced_gesture_events_.back(); 303 GestureEventWithLatencyInfo* last_event = &coalesced_gesture_events_.back();
344 if (last_event->CanCoalesceWith(gesture_event)) { 304 if (last_event->CanCoalesceWith(gesture_event)) {
345 last_event->CoalesceWith(gesture_event); 305 last_event->CoalesceWith(gesture_event);
346 return; 306 return;
347 } 307 }
348 308
349 if (!IsCompatibleScrollorPinch(gesture_event, *last_event)) { 309 if (!ui::IsCompatibleScrollorPinch(gesture_event.event, last_event->event)) {
350 coalesced_gesture_events_.push_back(gesture_event); 310 coalesced_gesture_events_.push_back(gesture_event);
351 return; 311 return;
352 } 312 }
353 313
354 GestureEventWithLatencyInfo scroll_event; 314 // Extract the last event in queue.
355 GestureEventWithLatencyInfo pinch_event; 315 blink::WebGestureEvent last_gesture_event =
356 scroll_event.event.modifiers |= gesture_event.event.modifiers; 316 coalesced_gesture_events_.back().event;
357 scroll_event.event.sourceDevice = gesture_event.event.sourceDevice; 317 DCHECK_LE(coalesced_gesture_events_.back().latency.trace_id(),
358 scroll_event.event.timeStampSeconds = gesture_event.event.timeStampSeconds; 318 gesture_event.latency.trace_id());
359 // Keep the oldest LatencyInfo. 319 ui::LatencyInfo oldest_latency = coalesced_gesture_events_.back().latency;
360 DCHECK_LE(last_event->latency.trace_id(), gesture_event.latency.trace_id()); 320 oldest_latency.set_coalesced();
361 scroll_event.latency = last_event->latency;
362 pinch_event = scroll_event;
363 scroll_event.event.type = WebInputEvent::GestureScrollUpdate;
364 pinch_event.event.type = WebInputEvent::GesturePinchUpdate;
365 pinch_event.event.x = gesture_event.event.type ==
366 WebInputEvent::GesturePinchUpdate ?
367 gesture_event.event.x : last_event->event.x;
368 pinch_event.event.y = gesture_event.event.type ==
369 WebInputEvent::GesturePinchUpdate ?
370 gesture_event.event.y : last_event->event.y;
371
372 gfx::Transform combined_scroll_pinch = GetTransformForEvent(*last_event);
373 // Only include the second-to-last event in the coalesced pair if it exists
374 // and can be combined with the new event.
375 if (unsent_events_count > 1) {
376 const GestureEventWithLatencyInfo& second_last_event =
377 coalesced_gesture_events_[coalesced_gesture_events_.size() - 2];
378 if (IsCompatibleScrollorPinch(gesture_event, second_last_event)) {
379 // Keep the oldest LatencyInfo.
380 DCHECK_LE(second_last_event.latency.trace_id(),
381 scroll_event.latency.trace_id());
382 scroll_event.latency = second_last_event.latency;
383 pinch_event.latency = second_last_event.latency;
384 combined_scroll_pinch.PreconcatTransform(
385 GetTransformForEvent(second_last_event));
386 coalesced_gesture_events_.pop_back();
387 }
388 }
389 combined_scroll_pinch.ConcatTransform(GetTransformForEvent(gesture_event));
390 coalesced_gesture_events_.pop_back(); 321 coalesced_gesture_events_.pop_back();
391 322
392 float combined_scale = 323 // Extract the second last event in queue.
393 SkMScalarToFloat(combined_scroll_pinch.matrix().get(0, 0)); 324 ui::ScopedWebInputEvent second_last_gesture_event = nullptr;
394 float combined_scroll_pinch_x = 325 if (unsent_events_count > 1 &&
395 SkMScalarToFloat(combined_scroll_pinch.matrix().get(0, 3)); 326 ui::IsCompatibleScrollorPinch(gesture_event.event,
396 float combined_scroll_pinch_y = 327 coalesced_gesture_events_.back().event)) {
397 SkMScalarToFloat(combined_scroll_pinch.matrix().get(1, 3)); 328 second_last_gesture_event =
398 scroll_event.event.data.scrollUpdate.deltaX = 329 ui::WebInputEventTraits::Clone(coalesced_gesture_events_.back().event);
399 (combined_scroll_pinch_x + pinch_event.event.x) / combined_scale - 330 DCHECK_LE(coalesced_gesture_events_.back().latency.trace_id(),
400 pinch_event.event.x; 331 oldest_latency.trace_id());
401 scroll_event.event.data.scrollUpdate.deltaY = 332 oldest_latency = coalesced_gesture_events_.back().latency;
402 (combined_scroll_pinch_y + pinch_event.event.y) / combined_scale - 333 oldest_latency.set_coalesced();
403 pinch_event.event.y; 334 coalesced_gesture_events_.pop_back();
335 }
336
337 std::pair<blink::WebGestureEvent, blink::WebGestureEvent> coalesced_events =
338 ui::CoalesceScrollAndPinch(
339 second_last_gesture_event
340 ? &ui::ToWebGestureEvent(*second_last_gesture_event)
341 : nullptr,
342 last_gesture_event, gesture_event.event);
343
344 GestureEventWithLatencyInfo scroll_event;
345 scroll_event.event = coalesced_events.first;
346 scroll_event.latency = oldest_latency;
347
348 GestureEventWithLatencyInfo pinch_event;
349 pinch_event.event = coalesced_events.second;
350 pinch_event.latency = oldest_latency;
351
404 coalesced_gesture_events_.push_back(scroll_event); 352 coalesced_gesture_events_.push_back(scroll_event);
405 pinch_event.event.data.pinchUpdate.scale = combined_scale;
406 coalesced_gesture_events_.push_back(pinch_event); 353 coalesced_gesture_events_.push_back(pinch_event);
407 } 354 }
408 355
409 size_t GestureEventQueue::EventsInFlightCount() const { 356 size_t GestureEventQueue::EventsInFlightCount() const {
410 if (coalesced_gesture_events_.empty()) 357 if (coalesced_gesture_events_.empty())
411 return 0; 358 return 0;
412 359
413 if (!ignore_next_ack_) 360 if (!ignore_next_ack_)
414 return 1; 361 return 1;
415 362
416 DCHECK_GT(coalesced_gesture_events_.size(), 1U); 363 DCHECK_GT(coalesced_gesture_events_.size(), 1U);
417 return 2; 364 return 2;
418 } 365 }
419 366
420 } // namespace content 367 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/renderer_host/input/gesture_event_queue.h ('k') | ui/events/blink/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698