| OLD | NEW |
| 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/render_widget_host_latency_tracker
.h" | 5 #include "content/browser/renderer_host/input/render_widget_host_latency_tracker
.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 void UpdateLatencyCoordinatesImpl(const WebMouseWheelEvent& wheel, | 50 void UpdateLatencyCoordinatesImpl(const WebMouseWheelEvent& wheel, |
| 51 LatencyInfo* latency, | 51 LatencyInfo* latency, |
| 52 float device_scale_factor) { | 52 float device_scale_factor) { |
| 53 latency->AddInputCoordinate(gfx::PointF(wheel.x * device_scale_factor, | 53 latency->AddInputCoordinate(gfx::PointF(wheel.x * device_scale_factor, |
| 54 wheel.y * device_scale_factor)); | 54 wheel.y * device_scale_factor)); |
| 55 } | 55 } |
| 56 | 56 |
| 57 void UpdateLatencyCoordinates(const WebInputEvent& event, | 57 void UpdateLatencyCoordinates(const WebInputEvent& event, |
| 58 float device_scale_factor, | 58 float device_scale_factor, |
| 59 LatencyInfo* latency) { | 59 LatencyInfo* latency) { |
| 60 if (WebInputEvent::isMouseEventType(event.type)) { | 60 if (WebInputEvent::isMouseEventType(event.type())) { |
| 61 UpdateLatencyCoordinatesImpl(static_cast<const WebMouseEvent&>(event), | 61 UpdateLatencyCoordinatesImpl(static_cast<const WebMouseEvent&>(event), |
| 62 latency, device_scale_factor); | 62 latency, device_scale_factor); |
| 63 } else if (WebInputEvent::isGestureEventType(event.type)) { | 63 } else if (WebInputEvent::isGestureEventType(event.type())) { |
| 64 UpdateLatencyCoordinatesImpl(static_cast<const WebGestureEvent&>(event), | 64 UpdateLatencyCoordinatesImpl(static_cast<const WebGestureEvent&>(event), |
| 65 latency, device_scale_factor); | 65 latency, device_scale_factor); |
| 66 } else if (WebInputEvent::isTouchEventType(event.type)) { | 66 } else if (WebInputEvent::isTouchEventType(event.type())) { |
| 67 UpdateLatencyCoordinatesImpl(static_cast<const WebTouchEvent&>(event), | 67 UpdateLatencyCoordinatesImpl(static_cast<const WebTouchEvent&>(event), |
| 68 latency, device_scale_factor); | 68 latency, device_scale_factor); |
| 69 } else if (event.type == WebInputEvent::MouseWheel) { | 69 } else if (event.type() == WebInputEvent::MouseWheel) { |
| 70 UpdateLatencyCoordinatesImpl(static_cast<const WebMouseWheelEvent&>(event), | 70 UpdateLatencyCoordinatesImpl(static_cast<const WebMouseWheelEvent&>(event), |
| 71 latency, device_scale_factor); | 71 latency, device_scale_factor); |
| 72 } | 72 } |
| 73 } | 73 } |
| 74 | 74 |
| 75 // Touch to scroll latency that is mostly under 1 second. | 75 // Touch to scroll latency that is mostly under 1 second. |
| 76 #define UMA_HISTOGRAM_TOUCH_TO_SCROLL_LATENCY(name, start, end) \ | 76 #define UMA_HISTOGRAM_TOUCH_TO_SCROLL_LATENCY(name, start, end) \ |
| 77 UMA_HISTOGRAM_CUSTOM_COUNTS( \ | 77 UMA_HISTOGRAM_CUSTOM_COUNTS( \ |
| 78 name, (end.event_time - start.event_time).InMicroseconds(), 1, 1000000, \ | 78 name, (end.event_time - start.event_time).InMicroseconds(), 1, 1000000, \ |
| 79 100) | 79 100) |
| (...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 544 | 544 |
| 545 void RenderWidgetHostLatencyTracker::OnInputEvent( | 545 void RenderWidgetHostLatencyTracker::OnInputEvent( |
| 546 const blink::WebInputEvent& event, | 546 const blink::WebInputEvent& event, |
| 547 LatencyInfo* latency) { | 547 LatencyInfo* latency) { |
| 548 DCHECK(latency); | 548 DCHECK(latency); |
| 549 if (latency->FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, | 549 if (latency->FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, |
| 550 latency_component_id_, NULL)) { | 550 latency_component_id_, NULL)) { |
| 551 return; | 551 return; |
| 552 } | 552 } |
| 553 | 553 |
| 554 if (event.timeStampSeconds && | 554 if (event.timeStampSeconds() && |
| 555 !latency->FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, | 555 !latency->FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, |
| 556 0, NULL)) { | 556 NULL)) { |
| 557 base::TimeTicks timestamp_now = base::TimeTicks::Now(); | 557 base::TimeTicks timestamp_now = base::TimeTicks::Now(); |
| 558 base::TimeTicks timestamp_original = base::TimeTicks() + | 558 base::TimeTicks timestamp_original = |
| 559 base::TimeDelta::FromSecondsD(event.timeStampSeconds); | 559 base::TimeTicks() + |
| 560 base::TimeDelta::FromSecondsD(event.timeStampSeconds()); |
| 560 | 561 |
| 561 // Timestamp from platform input can wrap, e.g. 32 bits timestamp | 562 // Timestamp from platform input can wrap, e.g. 32 bits timestamp |
| 562 // for Xserver and Window MSG time will wrap about 49.6 days. Do a | 563 // for Xserver and Window MSG time will wrap about 49.6 days. Do a |
| 563 // sanity check here and if wrap does happen, use TimeTicks::Now() | 564 // sanity check here and if wrap does happen, use TimeTicks::Now() |
| 564 // as the timestamp instead. | 565 // as the timestamp instead. |
| 565 if ((timestamp_now - timestamp_original).InDays() > 0) | 566 if ((timestamp_now - timestamp_original).InDays() > 0) |
| 566 timestamp_original = timestamp_now; | 567 timestamp_original = timestamp_now; |
| 567 | 568 |
| 568 latency->AddLatencyNumberWithTimestamp( | 569 latency->AddLatencyNumberWithTimestamp( |
| 569 ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, | 570 ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, |
| 570 0, | 571 0, |
| 571 0, | 572 0, |
| 572 timestamp_original, | 573 timestamp_original, |
| 573 1); | 574 1); |
| 574 } | 575 } |
| 575 | 576 |
| 576 latency->AddLatencyNumberWithTraceName( | 577 latency->AddLatencyNumberWithTraceName( |
| 577 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, latency_component_id_, | 578 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, latency_component_id_, |
| 578 ++last_event_id_, WebInputEvent::GetName(event.type)); | 579 ++last_event_id_, WebInputEvent::GetName(event.type())); |
| 579 | 580 |
| 580 UpdateLatencyCoordinates(event, device_scale_factor_, latency); | 581 UpdateLatencyCoordinates(event, device_scale_factor_, latency); |
| 581 | 582 |
| 582 if (event.type == blink::WebInputEvent::GestureScrollBegin) { | 583 if (event.type() == blink::WebInputEvent::GestureScrollBegin) { |
| 583 has_seen_first_gesture_scroll_update_ = false; | 584 has_seen_first_gesture_scroll_update_ = false; |
| 584 } else if (event.type == blink::WebInputEvent::GestureScrollUpdate) { | 585 } else if (event.type() == blink::WebInputEvent::GestureScrollUpdate) { |
| 585 // Make a copy of the INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT with a | 586 // Make a copy of the INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT with a |
| 586 // different name INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT. | 587 // different name INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT. |
| 587 // So we can track the latency specifically for scroll update events. | 588 // So we can track the latency specifically for scroll update events. |
| 588 LatencyInfo::LatencyComponent original_component; | 589 LatencyInfo::LatencyComponent original_component; |
| 589 if (latency->FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, | 590 if (latency->FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, |
| 590 &original_component)) { | 591 &original_component)) { |
| 591 latency->AddLatencyNumberWithTimestamp( | 592 latency->AddLatencyNumberWithTimestamp( |
| 592 has_seen_first_gesture_scroll_update_ | 593 has_seen_first_gesture_scroll_update_ |
| 593 ? ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT | 594 ? ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT |
| 594 : ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT, | 595 : ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT, |
| 595 latency_component_id_, original_component.sequence_number, | 596 latency_component_id_, original_component.sequence_number, |
| 596 original_component.event_time, original_component.event_count); | 597 original_component.event_time, original_component.event_count); |
| 597 } | 598 } |
| 598 | 599 |
| 599 has_seen_first_gesture_scroll_update_ = true; | 600 has_seen_first_gesture_scroll_update_ = true; |
| 600 } | 601 } |
| 601 } | 602 } |
| 602 | 603 |
| 603 void RenderWidgetHostLatencyTracker::OnInputEventAck( | 604 void RenderWidgetHostLatencyTracker::OnInputEventAck( |
| 604 const blink::WebInputEvent& event, | 605 const blink::WebInputEvent& event, |
| 605 LatencyInfo* latency, InputEventAckState ack_result) { | 606 LatencyInfo* latency, InputEventAckState ack_result) { |
| 606 DCHECK(latency); | 607 DCHECK(latency); |
| 607 | 608 |
| 608 // Latency ends when it is acked but does not cause render scheduling. | 609 // Latency ends when it is acked but does not cause render scheduling. |
| 609 bool rendering_scheduled = latency->FindLatency( | 610 bool rendering_scheduled = latency->FindLatency( |
| 610 ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN_COMPONENT, 0, nullptr); | 611 ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN_COMPONENT, 0, nullptr); |
| 611 rendering_scheduled |= latency->FindLatency( | 612 rendering_scheduled |= latency->FindLatency( |
| 612 ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL_COMPONENT, 0, nullptr); | 613 ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL_COMPONENT, 0, nullptr); |
| 613 | 614 |
| 614 if (WebInputEvent::isGestureEventType(event.type)) { | 615 if (WebInputEvent::isGestureEventType(event.type())) { |
| 615 if (!rendering_scheduled) { | 616 if (!rendering_scheduled) { |
| 616 latency->AddLatencyNumber( | 617 latency->AddLatencyNumber( |
| 617 ui::INPUT_EVENT_LATENCY_TERMINATED_GESTURE_COMPONENT, 0, 0); | 618 ui::INPUT_EVENT_LATENCY_TERMINATED_GESTURE_COMPONENT, 0, 0); |
| 618 // TODO(jdduke): Consider exposing histograms for gesture event types. | 619 // TODO(jdduke): Consider exposing histograms for gesture event types. |
| 619 } | 620 } |
| 620 return; | 621 return; |
| 621 } | 622 } |
| 622 | 623 |
| 623 if (WebInputEvent::isTouchEventType(event.type)) { | 624 if (WebInputEvent::isTouchEventType(event.type())) { |
| 624 const WebTouchEvent& touch_event = | 625 const WebTouchEvent& touch_event = |
| 625 *static_cast<const WebTouchEvent*>(&event); | 626 *static_cast<const WebTouchEvent*>(&event); |
| 626 if (event.type == WebInputEvent::TouchStart) { | 627 if (event.type() == WebInputEvent::TouchStart) { |
| 627 DCHECK(touch_event.touchesLength >= 1); | 628 DCHECK(touch_event.touchesLength >= 1); |
| 628 multi_finger_gesture_ = touch_event.touchesLength != 1; | 629 multi_finger_gesture_ = touch_event.touchesLength != 1; |
| 629 touch_start_default_prevented_ = | 630 touch_start_default_prevented_ = |
| 630 ack_result == INPUT_EVENT_ACK_STATE_CONSUMED; | 631 ack_result == INPUT_EVENT_ACK_STATE_CONSUMED; |
| 631 } | 632 } |
| 632 | 633 |
| 633 latency->AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0, 0); | 634 latency->AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0, 0); |
| 634 | 635 |
| 635 if (!rendering_scheduled) { | 636 if (!rendering_scheduled) { |
| 636 latency->AddLatencyNumber( | 637 latency->AddLatencyNumber( |
| 637 ui::INPUT_EVENT_LATENCY_TERMINATED_TOUCH_COMPONENT, 0, 0); | 638 ui::INPUT_EVENT_LATENCY_TERMINATED_TOUCH_COMPONENT, 0, 0); |
| 638 } | 639 } |
| 639 ComputeInputLatencyHistograms(event.type, latency_component_id_, *latency, | 640 ComputeInputLatencyHistograms(event.type(), latency_component_id_, *latency, |
| 640 ack_result); | 641 ack_result); |
| 641 return; | 642 return; |
| 642 } | 643 } |
| 643 | 644 |
| 644 if (event.type == WebInputEvent::MouseWheel) { | 645 if (event.type() == WebInputEvent::MouseWheel) { |
| 645 latency->AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0, 0); | 646 latency->AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0, 0); |
| 646 if (!rendering_scheduled) { | 647 if (!rendering_scheduled) { |
| 647 latency->AddLatencyNumber( | 648 latency->AddLatencyNumber( |
| 648 ui::INPUT_EVENT_LATENCY_TERMINATED_MOUSE_WHEEL_COMPONENT, 0, 0); | 649 ui::INPUT_EVENT_LATENCY_TERMINATED_MOUSE_WHEEL_COMPONENT, 0, 0); |
| 649 } | 650 } |
| 650 ComputeInputLatencyHistograms(event.type, latency_component_id_, *latency, | 651 ComputeInputLatencyHistograms(event.type(), latency_component_id_, *latency, |
| 651 ack_result); | 652 ack_result); |
| 652 return; | 653 return; |
| 653 } | 654 } |
| 654 | 655 |
| 655 if (WebInputEvent::isMouseEventType(event.type) && !rendering_scheduled) { | 656 if (WebInputEvent::isMouseEventType(event.type()) && !rendering_scheduled) { |
| 656 latency->AddLatencyNumber( | 657 latency->AddLatencyNumber( |
| 657 ui::INPUT_EVENT_LATENCY_TERMINATED_MOUSE_COMPONENT, 0, 0); | 658 ui::INPUT_EVENT_LATENCY_TERMINATED_MOUSE_COMPONENT, 0, 0); |
| 658 return; | 659 return; |
| 659 } | 660 } |
| 660 | 661 |
| 661 if (WebInputEvent::isKeyboardEventType(event.type) && !rendering_scheduled) { | 662 if (WebInputEvent::isKeyboardEventType(event.type()) && |
| 662 latency->AddLatencyNumber( | 663 !rendering_scheduled) { |
| 663 ui::INPUT_EVENT_LATENCY_TERMINATED_KEYBOARD_COMPONENT, 0, 0); | 664 latency->AddLatencyNumber( |
| 665 ui::INPUT_EVENT_LATENCY_TERMINATED_KEYBOARD_COMPONENT, 0, 0); |
| 664 return; | 666 return; |
| 665 } | 667 } |
| 666 } | 668 } |
| 667 | 669 |
| 668 void RenderWidgetHostLatencyTracker::OnSwapCompositorFrame( | 670 void RenderWidgetHostLatencyTracker::OnSwapCompositorFrame( |
| 669 std::vector<LatencyInfo>* latencies) { | 671 std::vector<LatencyInfo>* latencies) { |
| 670 DCHECK(latencies); | 672 DCHECK(latencies); |
| 671 for (LatencyInfo& latency : *latencies) { | 673 for (LatencyInfo& latency : *latencies) { |
| 672 AddLatencyInfoComponentIds(&latency, latency_component_id_); | 674 AddLatencyInfoComponentIds(&latency, latency_component_id_); |
| 673 latency.AddLatencyNumber( | 675 latency.AddLatencyNumber( |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 723 if (!latency.FindLatency( | 725 if (!latency.FindLatency( |
| 724 ui::INPUT_EVENT_LATENCY_GENERATE_SCROLL_UPDATE_FROM_MOUSE_WHEEL, 0, | 726 ui::INPUT_EVENT_LATENCY_GENERATE_SCROLL_UPDATE_FROM_MOUSE_WHEEL, 0, |
| 725 &mouse_wheel_scroll_update_component)) { | 727 &mouse_wheel_scroll_update_component)) { |
| 726 ComputeScrollLatencyHistograms( | 728 ComputeScrollLatencyHistograms( |
| 727 gpu_swap_begin_component, gpu_swap_end_component, latency_component_id_, | 729 gpu_swap_begin_component, gpu_swap_end_component, latency_component_id_, |
| 728 latency, is_running_navigation_hint_task); | 730 latency, is_running_navigation_hint_task); |
| 729 } | 731 } |
| 730 } | 732 } |
| 731 | 733 |
| 732 } // namespace content | 734 } // namespace content |
| OLD | NEW |