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

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

Issue 997283002: Coalesce async touch move events until the ack back from render (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 months 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/touch_event_queue.h" 5 #include "content/browser/renderer_host/input/touch_event_queue.h"
6 6
7 #include "base/auto_reset.h" 7 #include "base/auto_reset.h"
8 #include "base/stl_util.h" 8 #include "base/stl_util.h"
9 #include "base/trace_event/trace_event.h" 9 #include "base/trace_event/trace_event.h"
10 #include "content/browser/renderer_host/input/timeout_monitor.h" 10 #include "content/browser/renderer_host/input/timeout_monitor.h"
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after
365 TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client, 365 TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client,
366 const Config& config) 366 const Config& config)
367 : client_(client), 367 : client_(client),
368 dispatching_touch_ack_(false), 368 dispatching_touch_ack_(false),
369 dispatching_touch_(false), 369 dispatching_touch_(false),
370 has_handlers_(true), 370 has_handlers_(true),
371 has_handler_for_current_sequence_(false), 371 has_handler_for_current_sequence_(false),
372 drop_remaining_touches_in_sequence_(false), 372 drop_remaining_touches_in_sequence_(false),
373 touchmove_slop_suppressor_(new TouchMoveSlopSuppressor), 373 touchmove_slop_suppressor_(new TouchMoveSlopSuppressor),
374 send_touch_events_async_(false), 374 send_touch_events_async_(false),
375 uncancelable_touch_moves_pending_ack_count_(0),
375 last_sent_touch_timestamp_sec_(0) { 376 last_sent_touch_timestamp_sec_(0) {
376 DCHECK(client); 377 DCHECK(client);
377 if (config.touch_ack_timeout_supported) { 378 if (config.touch_ack_timeout_supported) {
378 timeout_handler_.reset( 379 timeout_handler_.reset(
379 new TouchTimeoutHandler(this, config.touch_ack_timeout_delay)); 380 new TouchTimeoutHandler(this, config.touch_ack_timeout_delay));
380 } 381 }
381 } 382 }
382 383
383 TouchEventQueue::~TouchEventQueue() { 384 TouchEventQueue::~TouchEventQueue() {
384 if (!touch_queue_.empty()) 385 if (!touch_queue_.empty())
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 432
432 touchmove_slop_suppressor_->ConfirmTouchEvent(ack_result); 433 touchmove_slop_suppressor_->ConfirmTouchEvent(ack_result);
433 434
434 if (touch_queue_.empty()) 435 if (touch_queue_.empty())
435 return; 436 return;
436 437
437 PopTouchEventToClient(ack_result, latency_info); 438 PopTouchEventToClient(ack_result, latency_info);
438 TryForwardNextEventToRenderer(); 439 TryForwardNextEventToRenderer();
439 } 440 }
440 441
442 void TouchEventQueue::ProcessUncancelableTouchMoveAck() {
443 TRACE_EVENT0("input", "TouchEventQueue::ProcessUncancelableTouchMoveAck");
444
445 DCHECK(!dispatching_touch_ack_);
446 dispatching_touch_ = false;
447
448 // Decrease the count once we receive the ack back from render for
449 // uncancelable touchmoves.
450 --uncancelable_touch_moves_pending_ack_count_;
451
452 // Send the next pending async touch move once we receive the ack.
tdresser 2015/03/27 13:34:44 What if the timer is still running?
lanwei 2015/03/31 13:07:49 Done.
453 if (pending_async_touchmove_ &&
454 uncancelable_touch_moves_pending_ack_count_ == 0) {
455 TouchEventWithLatencyInfo touch = *pending_async_touchmove_;
456 touch.event.cancelable = !send_touch_events_async_;
457 pending_async_touchmove_.reset();
458 touch_queue_.push_front(new CoalescedWebTouchEvent(touch, true));
459 SendTouchEventImmediately(&touch);
460 }
461 }
462
441 void TouchEventQueue::TryForwardNextEventToRenderer() { 463 void TouchEventQueue::TryForwardNextEventToRenderer() {
442 DCHECK(!dispatching_touch_ack_); 464 DCHECK(!dispatching_touch_ack_);
443 // If there are queued touch events, then try to forward them to the renderer 465 // If there are queued touch events, then try to forward them to the renderer
444 // immediately, or ACK the events back to the client if appropriate. 466 // immediately, or ACK the events back to the client if appropriate.
445 while (!touch_queue_.empty()) { 467 while (!touch_queue_.empty()) {
446 PreFilterResult filter_result = 468 PreFilterResult filter_result =
447 FilterBeforeForwarding(touch_queue_.front()->coalesced_event().event); 469 FilterBeforeForwarding(touch_queue_.front()->coalesced_event().event);
448 switch (filter_result) { 470 switch (filter_result) {
449 case ACK_WITH_NO_CONSUMER_EXISTS: 471 case ACK_WITH_NO_CONSUMER_EXISTS:
450 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS); 472 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
(...skipping 22 matching lines...) Expand all
473 // application be sent touches at key points in the gesture stream, 495 // application be sent touches at key points in the gesture stream,
474 // e.g., when the application slop region is exceeded or touchmove 496 // e.g., when the application slop region is exceeded or touchmove
475 // coalescing fails because of different modifiers. 497 // coalescing fails because of different modifiers.
476 bool send_touchmove_now = size() > 1; 498 bool send_touchmove_now = size() > 1;
477 send_touchmove_now |= pending_async_touchmove_ && 499 send_touchmove_now |= pending_async_touchmove_ &&
478 !pending_async_touchmove_->CanCoalesceWith(touch); 500 !pending_async_touchmove_->CanCoalesceWith(touch);
479 send_touchmove_now |= 501 send_touchmove_now |=
480 touch.event.timeStampSeconds >= 502 touch.event.timeStampSeconds >=
481 last_sent_touch_timestamp_sec_ + kAsyncTouchMoveIntervalSec; 503 last_sent_touch_timestamp_sec_ + kAsyncTouchMoveIntervalSec;
482 504
483 if (!send_touchmove_now) { 505 if (!send_touchmove_now ||
506 uncancelable_touch_moves_pending_ack_count_ > 0) {
484 if (!pending_async_touchmove_) { 507 if (!pending_async_touchmove_) {
485 pending_async_touchmove_.reset(new TouchEventWithLatencyInfo(touch)); 508 pending_async_touchmove_.reset(new TouchEventWithLatencyInfo(touch));
486 } else { 509 } else {
487 DCHECK(pending_async_touchmove_->CanCoalesceWith(touch)); 510 DCHECK(pending_async_touchmove_->CanCoalesceWith(touch));
488 pending_async_touchmove_->CoalesceWith(touch); 511 pending_async_touchmove_->CoalesceWith(touch);
489 } 512 }
490 DCHECK_EQ(1U, size()); 513 DCHECK_EQ(1U, size());
491 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); 514 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
492 // It's possible (though unlikely) that ack'ing the current touch will 515 // It's possible (though unlikely) that ack'ing the current touch will
493 // trigger the queueing of another touch event (e.g., a touchcancel). As 516 // trigger the queueing of another touch event (e.g., a touchcancel). As
494 // forwarding of the queued event will be deferred while the ack is being 517 // forwarding of the queued event will be deferred while the ack is being
495 // dispatched (see |OnTouchEvent()|), try forwarding it now. 518 // dispatched (see |OnTouchEvent()|), try forwarding it now.
496 TryForwardNextEventToRenderer(); 519 TryForwardNextEventToRenderer();
497 return; 520 return;
498 } 521 }
499 } 522 }
500 523
501 last_sent_touch_timestamp_sec_ = touch.event.timeStampSeconds; 524 last_sent_touch_timestamp_sec_ = touch.event.timeStampSeconds;
502
503 // Flush any pending async touch move. If it can be combined with the current 525 // Flush any pending async touch move. If it can be combined with the current
504 // (touchmove) event, great, otherwise send it immediately but separately. Its 526 // (touchmove) event, great, otherwise send it immediately but separately. Its
505 // ack will trigger forwarding of the original |touch| event. 527 // ack will trigger forwarding of the original |touch| event.
506 if (pending_async_touchmove_) { 528 if (pending_async_touchmove_) {
507 if (pending_async_touchmove_->CanCoalesceWith(touch)) { 529 if (pending_async_touchmove_->CanCoalesceWith(touch)) {
508 pending_async_touchmove_->CoalesceWith(touch); 530 pending_async_touchmove_->CoalesceWith(touch);
509 pending_async_touchmove_->event.cancelable = !send_touch_events_async_; 531 pending_async_touchmove_->event.cancelable = !send_touch_events_async_;
510 touch = *pending_async_touchmove_; 532 touch = *pending_async_touchmove_;
511 pending_async_touchmove_.reset(); 533 pending_async_touchmove_.reset();
512 } else { 534 } else {
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 touch_queue_.pop_front(); 663 touch_queue_.pop_front();
642 return event.Pass(); 664 return event.Pass();
643 } 665 }
644 666
645 void TouchEventQueue::SendTouchEventImmediately( 667 void TouchEventQueue::SendTouchEventImmediately(
646 TouchEventWithLatencyInfo* touch) { 668 TouchEventWithLatencyInfo* touch) {
647 // For touchmove events, compare touch points position from current event 669 // For touchmove events, compare touch points position from current event
648 // to last sent event and update touch points state. 670 // to last sent event and update touch points state.
649 if (touch->event.type == WebInputEvent::TouchMove) { 671 if (touch->event.type == WebInputEvent::TouchMove) {
650 CHECK(last_sent_touchevent_); 672 CHECK(last_sent_touchevent_);
673 // We increase the count when we send out a uncancelable touch move.
674 if (!touch->event.cancelable)
675 ++uncancelable_touch_moves_pending_ack_count_;
676
651 for (unsigned int i = 0; i < last_sent_touchevent_->touchesLength; ++i) { 677 for (unsigned int i = 0; i < last_sent_touchevent_->touchesLength; ++i) {
652 const WebTouchPoint& last_touch_point = 678 const WebTouchPoint& last_touch_point =
653 last_sent_touchevent_->touches[i]; 679 last_sent_touchevent_->touches[i];
654 // Touches with same id may not have same index in Touches array. 680 // Touches with same id may not have same index in Touches array.
655 for (unsigned int j = 0; j < touch->event.touchesLength; ++j) { 681 for (unsigned int j = 0; j < touch->event.touchesLength; ++j) {
656 const WebTouchPoint& current_touchmove_point = touch->event.touches[j]; 682 const WebTouchPoint& current_touchmove_point = touch->event.touches[j];
657 if (current_touchmove_point.id != last_touch_point.id) 683 if (current_touchmove_point.id != last_touch_point.id)
658 continue; 684 continue;
659 685
660 if (!HasPointChanged(last_touch_point, current_touchmove_point)) 686 if (!HasPointChanged(last_touch_point, current_touchmove_point))
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED) 776 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
751 send_touch_events_async_ = false; 777 send_touch_events_async_ = false;
752 has_handler_for_current_sequence_ |= 778 has_handler_for_current_sequence_ |=
753 ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS; 779 ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
754 } else if (WebTouchEventTraits::IsTouchSequenceEnd(event)) { 780 } else if (WebTouchEventTraits::IsTouchSequenceEnd(event)) {
755 has_handler_for_current_sequence_ = false; 781 has_handler_for_current_sequence_ = false;
756 } 782 }
757 } 783 }
758 784
759 } // namespace content 785 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698