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

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.
453 if (pending_async_touchmove_ &&
454 uncancelable_touch_moves_pending_ack_count_ == 0) {
455 TouchEventWithLatencyInfo touch = *pending_async_touchmove_;
456
457 // Dispatch the next pending async touch move when time expires.
458 if (touch.event.timeStampSeconds >=
459 last_sent_touch_timestamp_sec_ + kAsyncTouchMoveIntervalSec) {
460 touch.event.cancelable = !send_touch_events_async_;
tdresser 2015/03/31 14:44:07 send_touch_events_async_ should never be false her
lanwei 2015/04/01 13:14:21 You are right, it will always be async, I thought
461 pending_async_touchmove_.reset();
462 touch_queue_.push_front(new CoalescedWebTouchEvent(touch, true));
463 SendTouchEventImmediately(&touch);
464 }
465 }
466 }
467
441 void TouchEventQueue::TryForwardNextEventToRenderer() { 468 void TouchEventQueue::TryForwardNextEventToRenderer() {
442 DCHECK(!dispatching_touch_ack_); 469 DCHECK(!dispatching_touch_ack_);
443 // If there are queued touch events, then try to forward them to the renderer 470 // 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. 471 // immediately, or ACK the events back to the client if appropriate.
445 while (!touch_queue_.empty()) { 472 while (!touch_queue_.empty()) {
446 PreFilterResult filter_result = 473 PreFilterResult filter_result =
447 FilterBeforeForwarding(touch_queue_.front()->coalesced_event().event); 474 FilterBeforeForwarding(touch_queue_.front()->coalesced_event().event);
448 switch (filter_result) { 475 switch (filter_result) {
449 case ACK_WITH_NO_CONSUMER_EXISTS: 476 case ACK_WITH_NO_CONSUMER_EXISTS:
450 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS); 477 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, 500 // application be sent touches at key points in the gesture stream,
474 // e.g., when the application slop region is exceeded or touchmove 501 // e.g., when the application slop region is exceeded or touchmove
475 // coalescing fails because of different modifiers. 502 // coalescing fails because of different modifiers.
476 bool send_touchmove_now = size() > 1; 503 bool send_touchmove_now = size() > 1;
477 send_touchmove_now |= pending_async_touchmove_ && 504 send_touchmove_now |= pending_async_touchmove_ &&
478 !pending_async_touchmove_->CanCoalesceWith(touch); 505 !pending_async_touchmove_->CanCoalesceWith(touch);
479 send_touchmove_now |= 506 send_touchmove_now |=
480 touch.event.timeStampSeconds >= 507 touch.event.timeStampSeconds >=
481 last_sent_touch_timestamp_sec_ + kAsyncTouchMoveIntervalSec; 508 last_sent_touch_timestamp_sec_ + kAsyncTouchMoveIntervalSec;
482 509
483 if (!send_touchmove_now) { 510 if (!send_touchmove_now ||
511 uncancelable_touch_moves_pending_ack_count_ > 0) {
484 if (!pending_async_touchmove_) { 512 if (!pending_async_touchmove_) {
485 pending_async_touchmove_.reset(new TouchEventWithLatencyInfo(touch)); 513 pending_async_touchmove_.reset(new TouchEventWithLatencyInfo(touch));
486 } else { 514 } else {
487 DCHECK(pending_async_touchmove_->CanCoalesceWith(touch)); 515 DCHECK(pending_async_touchmove_->CanCoalesceWith(touch));
488 pending_async_touchmove_->CoalesceWith(touch); 516 pending_async_touchmove_->CoalesceWith(touch);
489 } 517 }
490 DCHECK_EQ(1U, size()); 518 DCHECK_EQ(1U, size());
491 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NOT_CONSUMED); 519 PopTouchEventToClient(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
492 // It's possible (though unlikely) that ack'ing the current touch will 520 // 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 521 // 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 522 // forwarding of the queued event will be deferred while the ack is being
495 // dispatched (see |OnTouchEvent()|), try forwarding it now. 523 // dispatched (see |OnTouchEvent()|), try forwarding it now.
496 TryForwardNextEventToRenderer(); 524 TryForwardNextEventToRenderer();
497 return; 525 return;
498 } 526 }
499 } 527 }
500 528
501 last_sent_touch_timestamp_sec_ = touch.event.timeStampSeconds; 529 last_sent_touch_timestamp_sec_ = touch.event.timeStampSeconds;
502
503 // Flush any pending async touch move. If it can be combined with the current 530 // 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 531 // (touchmove) event, great, otherwise send it immediately but separately. Its
505 // ack will trigger forwarding of the original |touch| event. 532 // ack will trigger forwarding of the original |touch| event.
506 if (pending_async_touchmove_) { 533 if (pending_async_touchmove_) {
507 if (pending_async_touchmove_->CanCoalesceWith(touch)) { 534 if (pending_async_touchmove_->CanCoalesceWith(touch)) {
508 pending_async_touchmove_->CoalesceWith(touch); 535 pending_async_touchmove_->CoalesceWith(touch);
509 pending_async_touchmove_->event.cancelable = !send_touch_events_async_; 536 pending_async_touchmove_->event.cancelable = !send_touch_events_async_;
510 touch = *pending_async_touchmove_; 537 touch = *pending_async_touchmove_;
511 pending_async_touchmove_.reset(); 538 pending_async_touchmove_.reset();
512 } else { 539 } else {
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 touch_queue_.pop_front(); 668 touch_queue_.pop_front();
642 return event.Pass(); 669 return event.Pass();
643 } 670 }
644 671
645 void TouchEventQueue::SendTouchEventImmediately( 672 void TouchEventQueue::SendTouchEventImmediately(
646 TouchEventWithLatencyInfo* touch) { 673 TouchEventWithLatencyInfo* touch) {
647 // For touchmove events, compare touch points position from current event 674 // For touchmove events, compare touch points position from current event
648 // to last sent event and update touch points state. 675 // to last sent event and update touch points state.
649 if (touch->event.type == WebInputEvent::TouchMove) { 676 if (touch->event.type == WebInputEvent::TouchMove) {
650 CHECK(last_sent_touchevent_); 677 CHECK(last_sent_touchevent_);
678 // We increase the count when we send out a uncancelable touch move.
679 if (!touch->event.cancelable)
680 ++uncancelable_touch_moves_pending_ack_count_;
681
651 for (unsigned int i = 0; i < last_sent_touchevent_->touchesLength; ++i) { 682 for (unsigned int i = 0; i < last_sent_touchevent_->touchesLength; ++i) {
652 const WebTouchPoint& last_touch_point = 683 const WebTouchPoint& last_touch_point =
653 last_sent_touchevent_->touches[i]; 684 last_sent_touchevent_->touches[i];
654 // Touches with same id may not have same index in Touches array. 685 // Touches with same id may not have same index in Touches array.
655 for (unsigned int j = 0; j < touch->event.touchesLength; ++j) { 686 for (unsigned int j = 0; j < touch->event.touchesLength; ++j) {
656 const WebTouchPoint& current_touchmove_point = touch->event.touches[j]; 687 const WebTouchPoint& current_touchmove_point = touch->event.touches[j];
657 if (current_touchmove_point.id != last_touch_point.id) 688 if (current_touchmove_point.id != last_touch_point.id)
658 continue; 689 continue;
659 690
660 if (!HasPointChanged(last_touch_point, current_touchmove_point)) 691 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) 781 if (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED)
751 send_touch_events_async_ = false; 782 send_touch_events_async_ = false;
752 has_handler_for_current_sequence_ |= 783 has_handler_for_current_sequence_ |=
753 ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS; 784 ack_result != INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS;
754 } else if (WebTouchEventTraits::IsTouchSequenceEnd(event)) { 785 } else if (WebTouchEventTraits::IsTouchSequenceEnd(event)) {
755 has_handler_for_current_sequence_ = false; 786 has_handler_for_current_sequence_ = false;
756 } 787 }
757 } 788 }
758 789
759 } // namespace content 790 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698