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

Side by Side Diff: content/browser/renderer_host/input/input_router_impl.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, 7 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/input_router_impl.h" 5 #include "content/browser/renderer_host/input/input_router_impl.h"
6 6
7 #include <math.h> 7 #include <math.h>
8 8
9 #include "base/auto_reset.h" 9 #include "base/auto_reset.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 const ui::LatencyInfo& latency_info, 349 const ui::LatencyInfo& latency_info,
350 bool is_keyboard_shortcut) { 350 bool is_keyboard_shortcut) {
351 output_stream_validator_.Validate(input_event); 351 output_stream_validator_.Validate(input_event);
352 352
353 if (OfferToClient(input_event, latency_info)) 353 if (OfferToClient(input_event, latency_info))
354 return; 354 return;
355 355
356 OfferToRenderer(input_event, latency_info, is_keyboard_shortcut); 356 OfferToRenderer(input_event, latency_info, is_keyboard_shortcut);
357 357
358 // Touch events should always indicate in the event whether they are 358 // Touch events should always indicate in the event whether they are
359 // cancelable (respect ACK disposition) or not. 359 // cancelable (respect ACK disposition) or not except touchmove.
360 bool ignores_ack = WebInputEventTraits::IgnoresAckDisposition(input_event); 360 bool needs_synthetic_ack =
361 if (WebInputEvent::isTouchEventType(input_event.type)) { 361 !WebInputEventTraits::WillReceiveAckFromRenderer(input_event);
362
363 if (WebInputEvent::isTouchEventType(input_event.type) &&
364 input_event.type != WebInputEvent::TouchMove) {
362 const WebTouchEvent& touch = static_cast<const WebTouchEvent&>(input_event); 365 const WebTouchEvent& touch = static_cast<const WebTouchEvent&>(input_event);
363 DCHECK_NE(ignores_ack, !!touch.cancelable); 366 DCHECK_EQ(needs_synthetic_ack, !touch.cancelable);
364 } 367 }
365 368
366 // If we don't care about the ack disposition, send the ack immediately. 369 // The synthetic acks are sent immediately.
367 if (ignores_ack) { 370 if (needs_synthetic_ack) {
368 ProcessInputEventAck(input_event.type, 371 ProcessInputEventAck(
369 INPUT_EVENT_ACK_STATE_IGNORED, 372 input_event.type, INPUT_EVENT_ACK_STATE_IGNORED, latency_info,
370 latency_info, 373 WebInputEventTraits::GetUniqueTouchEventId(input_event),
371 IGNORING_DISPOSITION); 374 IGNORING_DISPOSITION);
372 } 375 }
373 } 376 }
374 377
375 bool InputRouterImpl::OfferToClient(const WebInputEvent& input_event, 378 bool InputRouterImpl::OfferToClient(const WebInputEvent& input_event,
376 const ui::LatencyInfo& latency_info) { 379 const ui::LatencyInfo& latency_info) {
377 bool consumed = false; 380 bool consumed = false;
378 381
379 InputEventAckState filter_ack = 382 InputEventAckState filter_ack =
380 client_->FilterInputEvent(input_event, latency_info); 383 client_->FilterInputEvent(input_event, latency_info);
381 switch (filter_ack) { 384 switch (filter_ack) {
382 case INPUT_EVENT_ACK_STATE_CONSUMED: 385 case INPUT_EVENT_ACK_STATE_CONSUMED:
383 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS: 386 case INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS:
384 // Send the ACK and early exit. 387 // Send the ACK and early exit.
385 next_mouse_move_.reset(); 388 next_mouse_move_.reset();
386 ProcessInputEventAck(input_event.type, filter_ack, latency_info, CLIENT); 389 ProcessInputEventAck(
390 input_event.type, filter_ack, latency_info,
391 WebInputEventTraits::GetUniqueTouchEventId(input_event), CLIENT);
387 // WARNING: |this| may be deleted at this point. 392 // WARNING: |this| may be deleted at this point.
388 consumed = true; 393 consumed = true;
389 break; 394 break;
390 case INPUT_EVENT_ACK_STATE_UNKNOWN: 395 case INPUT_EVENT_ACK_STATE_UNKNOWN:
391 // Simply drop the event. 396 // Simply drop the event.
392 consumed = true; 397 consumed = true;
393 break; 398 break;
394 default: 399 default:
395 break; 400 break;
396 } 401 }
397 402
398 return consumed; 403 return consumed;
399 } 404 }
400 405
401 bool InputRouterImpl::OfferToRenderer(const WebInputEvent& input_event, 406 bool InputRouterImpl::OfferToRenderer(const WebInputEvent& input_event,
402 const ui::LatencyInfo& latency_info, 407 const ui::LatencyInfo& latency_info,
403 bool is_keyboard_shortcut) { 408 bool is_keyboard_shortcut) {
404 if (Send(new InputMsg_HandleInputEvent( 409 if (Send(new InputMsg_HandleInputEvent(
405 routing_id(), &input_event, latency_info, is_keyboard_shortcut))) { 410 routing_id(), &input_event, latency_info, is_keyboard_shortcut))) {
406 // Ack messages for ignored ack event types should never be sent by the 411 // Ack messages for ignored ack event types should never be sent by the
407 // renderer. Consequently, such event types should not affect event time 412 // renderer. Consequently, such event types should not affect event time
408 // or in-flight event count metrics. 413 // or in-flight event count metrics.
409 if (!WebInputEventTraits::IgnoresAckDisposition(input_event)) { 414 if (WebInputEventTraits::WillReceiveAckFromRenderer(input_event)) {
410 input_event_start_time_ = TimeTicks::Now(); 415 input_event_start_time_ = TimeTicks::Now();
411 client_->IncrementInFlightEventCount(); 416 client_->IncrementInFlightEventCount();
412 } 417 }
413 return true; 418 return true;
414 } 419 }
415 return false; 420 return false;
416 } 421 }
417 422
418 void InputRouterImpl::OnInputEventAck( 423 void InputRouterImpl::OnInputEventAck(const InputEventAck& ack) {
419 const InputHostMsg_HandleInputEvent_ACK_Params& ack) {
420 client_->DecrementInFlightEventCount(); 424 client_->DecrementInFlightEventCount();
421
422 // Log the time delta for processing an input event. 425 // Log the time delta for processing an input event.
423 TimeDelta delta = TimeTicks::Now() - input_event_start_time_; 426 TimeDelta delta = TimeTicks::Now() - input_event_start_time_;
424 UMA_HISTOGRAM_TIMES("MPArch.IIR_InputEventDelta", delta); 427 UMA_HISTOGRAM_TIMES("MPArch.IIR_InputEventDelta", delta);
425 428
426 if (ack.overscroll) { 429 if (ack.overscroll) {
427 DCHECK(ack.type == WebInputEvent::MouseWheel || 430 DCHECK(ack.type == WebInputEvent::MouseWheel ||
428 ack.type == WebInputEvent::GestureScrollUpdate); 431 ack.type == WebInputEvent::GestureScrollUpdate);
429 OnDidOverscroll(*ack.overscroll); 432 OnDidOverscroll(*ack.overscroll);
430 } 433 }
431 434
432 ProcessInputEventAck(ack.type, ack.state, ack.latency, RENDERER); 435 ProcessInputEventAck(ack.type, ack.state, ack.latency,
433 // WARNING: |this| may be deleted at this point. 436 ack.unique_touch_event_id, RENDERER);
434
435 // This is used only for testing, and the other end does not use the
436 // source object. On linux, specifying
437 // Source<RenderWidgetHost> results in a very strange
438 // runtime error in the epilogue of the enclosing
439 // (ProcessInputEventAck) method, but not on other platforms; using
440 // 'void' instead is just as safe (since NotificationSource
441 // is not actually typesafe) and avoids this error.
442 int type = static_cast<int>(ack.type);
443 NotificationService::current()->Notify(
444 NOTIFICATION_RENDER_WIDGET_HOST_DID_RECEIVE_INPUT_EVENT_ACK,
445 Source<void>(this),
446 Details<int>(&type));
447 } 437 }
448 438
449 void InputRouterImpl::OnDidOverscroll(const DidOverscrollParams& params) { 439 void InputRouterImpl::OnDidOverscroll(const DidOverscrollParams& params) {
450 client_->DidOverscroll(params); 440 client_->DidOverscroll(params);
451 } 441 }
452 442
453 void InputRouterImpl::OnMsgMoveCaretAck() { 443 void InputRouterImpl::OnMsgMoveCaretAck() {
454 move_caret_pending_ = false; 444 move_caret_pending_ = false;
455 if (next_move_caret_) 445 if (next_move_caret_)
456 SendMoveCaret(next_move_caret_.Pass()); 446 SendMoveCaret(next_move_caret_.Pass());
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 // TOUCH_ACTION_NONE should disable the touch ack timeout. 485 // TOUCH_ACTION_NONE should disable the touch ack timeout.
496 UpdateTouchAckTimeoutEnabled(); 486 UpdateTouchAckTimeoutEnabled();
497 } 487 }
498 488
499 void InputRouterImpl::OnDidStopFlinging() { 489 void InputRouterImpl::OnDidStopFlinging() {
500 // TODO(jdduke): Track fling status to allow flush notifications after a fling 490 // TODO(jdduke): Track fling status to allow flush notifications after a fling
501 // has terminated, crbug.com/483037. 491 // has terminated, crbug.com/483037.
502 client_->DidStopFlinging(); 492 client_->DidStopFlinging();
503 } 493 }
504 494
505 void InputRouterImpl::ProcessInputEventAck( 495 void InputRouterImpl::ProcessInputEventAck(WebInputEvent::Type event_type,
506 WebInputEvent::Type event_type, 496 InputEventAckState ack_result,
507 InputEventAckState ack_result, 497 const ui::LatencyInfo& latency_info,
508 const ui::LatencyInfo& latency_info, 498 uint32 unique_touch_event_id,
509 AckSource ack_source) { 499 AckSource ack_source) {
510 TRACE_EVENT2("input", "InputRouterImpl::ProcessInputEventAck", 500 TRACE_EVENT2("input", "InputRouterImpl::ProcessInputEventAck",
511 "type", WebInputEventTraits::GetName(event_type), 501 "type", WebInputEventTraits::GetName(event_type),
512 "ack", GetEventAckName(ack_result)); 502 "ack", GetEventAckName(ack_result));
513 503
514 // Note: The keyboard ack must be treated carefully, as it may result in 504 // Note: The keyboard ack must be treated carefully, as it may result in
515 // synchronous destruction of |this|. Handling immediately guards against 505 // synchronous destruction of |this|. Handling immediately guards against
516 // future references to |this|, as with |auto_reset_current_ack_source| below. 506 // future references to |this|, as with |auto_reset_current_ack_source| below.
517 if (WebInputEvent::isKeyboardEventType(event_type)) { 507 if (WebInputEvent::isKeyboardEventType(event_type)) {
518 ProcessKeyboardAck(event_type, ack_result); 508 ProcessKeyboardAck(event_type, ack_result);
519 // WARNING: |this| may be deleted at this point. 509 // WARNING: |this| may be deleted at this point.
520 return; 510 return;
521 } 511 }
522 512
523 base::AutoReset<AckSource> auto_reset_current_ack_source( 513 base::AutoReset<AckSource> auto_reset_current_ack_source(
524 &current_ack_source_, ack_source); 514 &current_ack_source_, ack_source);
525 515
526 if (WebInputEvent::isMouseEventType(event_type)) { 516 if (WebInputEvent::isMouseEventType(event_type)) {
527 ProcessMouseAck(event_type, ack_result); 517 ProcessMouseAck(event_type, ack_result);
528 } else if (event_type == WebInputEvent::MouseWheel) { 518 } else if (event_type == WebInputEvent::MouseWheel) {
529 ProcessWheelAck(ack_result, latency_info); 519 ProcessWheelAck(ack_result, latency_info);
530 } else if (WebInputEvent::isTouchEventType(event_type)) { 520 } else if (WebInputEvent::isTouchEventType(event_type)) {
531 ProcessTouchAck(ack_result, latency_info); 521 ProcessTouchAck(ack_result, latency_info, unique_touch_event_id);
532 } else if (WebInputEvent::isGestureEventType(event_type)) { 522 } else if (WebInputEvent::isGestureEventType(event_type)) {
533 ProcessGestureAck(event_type, ack_result, latency_info); 523 ProcessGestureAck(event_type, ack_result, latency_info);
534 } else if (event_type != WebInputEvent::Undefined) { 524 } else if (event_type != WebInputEvent::Undefined) {
535 ack_handler_->OnUnexpectedEventAck(InputAckHandler::BAD_ACK_MESSAGE); 525 ack_handler_->OnUnexpectedEventAck(InputAckHandler::BAD_ACK_MESSAGE);
536 } 526 }
537 527
538 SignalFlushedIfNecessary(); 528 SignalFlushedIfNecessary();
539 } 529 }
540 530
541 void InputRouterImpl::ProcessKeyboardAck(blink::WebInputEvent::Type type, 531 void InputRouterImpl::ProcessKeyboardAck(blink::WebInputEvent::Type type,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
600 } 590 }
601 } 591 }
602 592
603 void InputRouterImpl::ProcessGestureAck(WebInputEvent::Type type, 593 void InputRouterImpl::ProcessGestureAck(WebInputEvent::Type type,
604 InputEventAckState ack_result, 594 InputEventAckState ack_result,
605 const ui::LatencyInfo& latency) { 595 const ui::LatencyInfo& latency) {
606 // |gesture_event_queue_| will forward to OnGestureEventAck when appropriate. 596 // |gesture_event_queue_| will forward to OnGestureEventAck when appropriate.
607 gesture_event_queue_.ProcessGestureAck(ack_result, type, latency); 597 gesture_event_queue_.ProcessGestureAck(ack_result, type, latency);
608 } 598 }
609 599
610 void InputRouterImpl::ProcessTouchAck( 600 void InputRouterImpl::ProcessTouchAck(InputEventAckState ack_result,
611 InputEventAckState ack_result, 601 const ui::LatencyInfo& latency,
612 const ui::LatencyInfo& latency) { 602 uint32 unique_touch_event_id) {
613 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate. 603 // |touch_event_queue_| will forward to OnTouchEventAck when appropriate.
614 touch_event_queue_.ProcessTouchAck(ack_result, latency); 604 touch_event_queue_.ProcessTouchAck(ack_result, latency,
605 unique_touch_event_id);
615 } 606 }
616 607
617 void InputRouterImpl::UpdateTouchAckTimeoutEnabled() { 608 void InputRouterImpl::UpdateTouchAckTimeoutEnabled() {
618 // Mobile sites tend to be well-behaved with respect to touch handling, so 609 // Mobile sites tend to be well-behaved with respect to touch handling, so
619 // they have less need for the touch timeout fallback. 610 // they have less need for the touch timeout fallback.
620 const bool fixed_page_scale = (current_view_flags_ & FIXED_PAGE_SCALE) != 0; 611 const bool fixed_page_scale = (current_view_flags_ & FIXED_PAGE_SCALE) != 0;
621 const bool mobile_viewport = (current_view_flags_ & MOBILE_VIEWPORT) != 0; 612 const bool mobile_viewport = (current_view_flags_ & MOBILE_VIEWPORT) != 0;
622 613
623 // TOUCH_ACTION_NONE will prevent scrolling, in which case the timeout serves 614 // TOUCH_ACTION_NONE will prevent scrolling, in which case the timeout serves
624 // little purpose. It's also a strong signal that touch handling is critical 615 // little purpose. It's also a strong signal that touch handling is critical
(...skipping 12 matching lines...) Expand all
637 return; 628 return;
638 629
639 if (HasPendingEvents()) 630 if (HasPendingEvents())
640 return; 631 return;
641 632
642 flush_requested_ = false; 633 flush_requested_ = false;
643 client_->DidFlush(); 634 client_->DidFlush();
644 } 635 }
645 636
646 } // namespace content 637 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698