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" |
mfomitchev
2017/04/04 14:59:05
General comment: I am wondering if we should split
tdresser
2017/05/01 15:49:21
I agree this is getting a bit unwieldy, but it isn
| |
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_functions.h" | 10 #include "base/metrics/histogram_functions.h" |
11 #include "base/metrics/histogram_macros.h" | 11 #include "base/metrics/histogram_macros.h" |
12 #include "build/build_config.h" | 12 #include "build/build_config.h" |
13 #include "components/rappor/public/rappor_utils.h" | 13 #include "components/rappor/public/rappor_utils.h" |
14 #include "content/browser/renderer_host/render_widget_host_delegate.h" | 14 #include "content/browser/renderer_host/render_widget_host_delegate.h" |
15 #include "content/public/browser/content_browser_client.h" | 15 #include "content/public/browser/content_browser_client.h" |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
127 base::HistogramBase::kUmaTargetedHistogramFlag) \ | 127 base::HistogramBase::kUmaTargetedHistogramFlag) \ |
128 ->Add((end.last_event_time - start.first_event_time).InMicroseconds()); | 128 ->Add((end.last_event_time - start.first_event_time).InMicroseconds()); |
129 | 129 |
130 std::string LatencySourceEventTypeToInputModalityString( | 130 std::string LatencySourceEventTypeToInputModalityString( |
131 ui::SourceEventType type) { | 131 ui::SourceEventType type) { |
132 switch (type) { | 132 switch (type) { |
133 case ui::SourceEventType::WHEEL: | 133 case ui::SourceEventType::WHEEL: |
134 return "Wheel"; | 134 return "Wheel"; |
135 case ui::SourceEventType::TOUCH: | 135 case ui::SourceEventType::TOUCH: |
136 return "Touch"; | 136 return "Touch"; |
137 case ui::SourceEventType::KEY: | |
138 return "Key"; | |
137 default: | 139 default: |
138 return ""; | 140 return ""; |
139 } | 141 } |
140 } | 142 } |
141 | 143 |
142 std::string WebInputEventTypeToInputModalityString(WebInputEvent::Type type) { | 144 std::string WebInputEventTypeToInputModalityString(WebInputEvent::Type type) { |
143 if (type == blink::WebInputEvent::MouseWheel) { | 145 if (type == blink::WebInputEvent::MouseWheel) { |
144 return "Wheel"; | 146 return "Wheel"; |
145 } else if (WebInputEvent::isKeyboardEventType(type)) { | 147 } else if (WebInputEvent::isKeyboardEventType(type)) { |
146 return "Key"; | 148 return "Key"; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
183 | 185 |
184 // This UMA metric tracks the time from when the original touch event is | 186 // This UMA metric tracks the time from when the original touch event is |
185 // created to when the scroll gesture results in final frame swap. | 187 // created to when the scroll gesture results in final frame swap. |
186 for (size_t i = 0; i < original_component.event_count; i++) { | 188 for (size_t i = 0; i < original_component.event_count; i++) { |
187 UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS( | 189 UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS( |
188 "Event.Latency.TouchToScrollUpdateSwapBegin", original_component, | 190 "Event.Latency.TouchToScrollUpdateSwapBegin", original_component, |
189 gpu_swap_begin_component); | 191 gpu_swap_begin_component); |
190 } | 192 } |
191 } | 193 } |
192 | 194 |
193 void ComputeTouchAndWheelScrollLatencyHistograms( | 195 void ComputeEndToEndLatencyHistograms( |
194 RenderWidgetHostDelegate* render_widget_host_delegate, | 196 RenderWidgetHostDelegate* render_widget_host_delegate, |
195 const ui::LatencyInfo::LatencyComponent& gpu_swap_begin_component, | 197 const ui::LatencyInfo::LatencyComponent& gpu_swap_begin_component, |
196 const ui::LatencyInfo::LatencyComponent& gpu_swap_end_component, | 198 const ui::LatencyInfo::LatencyComponent& gpu_swap_end_component, |
197 int64_t latency_component_id, | 199 int64_t latency_component_id, |
198 const ui::LatencyInfo& latency) { | 200 const ui::LatencyInfo& latency) { |
199 DCHECK(!latency.coalesced()); | 201 DCHECK(!latency.coalesced()); |
200 if (latency.coalesced()) | 202 if (latency.coalesced()) |
201 return; | 203 return; |
202 | 204 |
203 LatencyInfo::LatencyComponent original_component; | 205 LatencyInfo::LatencyComponent original_component; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
239 if (input_modality == "Touch") { | 241 if (input_modality == "Touch") { |
240 UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS( | 242 UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS( |
241 "Event.Latency.ScrollUpdate.Touch.TimeToScrollUpdateSwapBegin2", | 243 "Event.Latency.ScrollUpdate.Touch.TimeToScrollUpdateSwapBegin2", |
242 original_component, gpu_swap_begin_component); | 244 original_component, gpu_swap_begin_component); |
243 | 245 |
244 RAPPOR_TOUCH_WHEEL_TO_SCROLL_LATENCY( | 246 RAPPOR_TOUCH_WHEEL_TO_SCROLL_LATENCY( |
245 render_widget_host_delegate, | 247 render_widget_host_delegate, |
246 "Event.Latency.ScrollUpdate.Touch.TimeToScrollUpdateSwapBegin2", | 248 "Event.Latency.ScrollUpdate.Touch.TimeToScrollUpdateSwapBegin2", |
247 original_component, gpu_swap_begin_component); | 249 original_component, gpu_swap_begin_component); |
248 } | 250 } |
251 } else if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, | |
252 &original_component)) { | |
253 if (input_modality == "Key") { | |
254 UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS( | |
255 "Event.Latency.EndToEnd.Key", original_component, | |
256 gpu_swap_begin_component); | |
257 } | |
249 } else { | 258 } else { |
250 // No original component found. | 259 // No original component found. |
251 return; | 260 return; |
252 } | 261 } |
253 | 262 |
254 LatencyInfo::LatencyComponent rendering_scheduled_component; | 263 LatencyInfo::LatencyComponent rendering_scheduled_component; |
255 bool rendering_scheduled_on_main = latency.FindLatency( | 264 bool rendering_scheduled_on_main = latency.FindLatency( |
256 ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN_COMPONENT, 0, | 265 ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN_COMPONENT, 0, |
257 &rendering_scheduled_component); | 266 &rendering_scheduled_component); |
258 if (!rendering_scheduled_on_main) { | 267 if (!rendering_scheduled_on_main) { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
355 WebInputEvent::Type type, | 364 WebInputEvent::Type type, |
356 int64_t latency_component_id, | 365 int64_t latency_component_id, |
357 const LatencyInfo& latency, | 366 const LatencyInfo& latency, |
358 InputEventAckState ack_result) { | 367 InputEventAckState ack_result) { |
359 // If this event was coalesced into another event, ignore it, as the event it | 368 // If this event was coalesced into another event, ignore it, as the event it |
360 // was coalesced into will reflect the full latency. | 369 // was coalesced into will reflect the full latency. |
361 if (latency.coalesced()) | 370 if (latency.coalesced()) |
362 return; | 371 return; |
363 | 372 |
364 if (type != blink::WebInputEvent::MouseWheel && | 373 if (type != blink::WebInputEvent::MouseWheel && |
365 !WebInputEvent::isTouchEventType(type)) { | 374 !WebInputEvent::isTouchEventType(type) && |
375 !WebInputEvent::isKeyboardEventType(type)) { | |
366 return; | 376 return; |
367 } | 377 } |
368 | 378 |
369 LatencyInfo::LatencyComponent rwh_component; | 379 LatencyInfo::LatencyComponent rwh_component; |
370 if (!latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, | 380 if (!latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, |
371 latency_component_id, &rwh_component)) { | 381 latency_component_id, &rwh_component)) { |
372 return; | 382 return; |
373 } | 383 } |
374 DCHECK_EQ(rwh_component.event_count, 1u); | 384 DCHECK_EQ(rwh_component.event_count, 1u); |
375 | 385 |
376 LatencyInfo::LatencyComponent ui_component; | 386 LatencyInfo::LatencyComponent ui_component; |
377 if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0, | 387 if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0, |
378 &ui_component)) { | 388 &ui_component)) { |
379 DCHECK_EQ(ui_component.event_count, 1u); | 389 DCHECK_EQ(ui_component.event_count, 1u); |
380 base::TimeDelta ui_delta = | 390 base::TimeDelta ui_delta = |
381 rwh_component.last_event_time - ui_component.first_event_time; | 391 rwh_component.last_event_time - ui_component.first_event_time; |
382 | 392 |
383 if (type == blink::WebInputEvent::MouseWheel) { | 393 if (type == blink::WebInputEvent::MouseWheel) { |
384 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.Browser.WheelUI", | 394 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.Browser.WheelUI", |
385 ui_delta.InMicroseconds(), 1, 20000, 100); | 395 ui_delta.InMicroseconds(), 1, 20000, 100); |
386 } else { | 396 } else if (WebInputEvent::isTouchEventType(type)) { |
387 DCHECK(WebInputEvent::isTouchEventType(type)); | |
388 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.Browser.TouchUI", | 397 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.Browser.TouchUI", |
389 ui_delta.InMicroseconds(), 1, 20000, 100); | 398 ui_delta.InMicroseconds(), 1, 20000, 100); |
399 } else if (WebInputEvent::isKeyboardEventType(type)) { | |
mfomitchev
2017/04/04 14:59:05
Can we make this a DCHECK instead of an if?
tdresser
2017/05/01 15:49:21
Added an else with NOTREACHED().
| |
400 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.Browser.KeyUI", | |
401 ui_delta.InMicroseconds(), 1, 20000, 50); | |
390 } | 402 } |
391 } | 403 } |
392 | 404 |
393 // Both tap and scroll gestures depend on the disposition of the touch start | 405 // Both tap and scroll gestures depend on the disposition of the touch start |
394 // and the current touch. For touch start, touch_start_default_prevented_ == | 406 // and the current touch. For touch start, touch_start_default_prevented_ == |
mfomitchev
2017/04/04 14:59:06
Does the second sentence of this comment applies t
tdresser
2017/05/01 15:49:21
Sorry, a bit confused here. The second sentence st
| |
395 // (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED). | 407 // (ack_result == INPUT_EVENT_ACK_STATE_CONSUMED). |
396 bool action_prevented = touch_start_default_prevented_ || | 408 bool action_prevented = touch_start_default_prevented_ || |
397 ack_result == INPUT_EVENT_ACK_STATE_CONSUMED; | 409 ack_result == INPUT_EVENT_ACK_STATE_CONSUMED; |
tdresser
2017/05/01 15:49:21
Ack, this is still broken in the non-touch case. I
| |
398 | 410 |
399 std::string event_name = WebInputEvent::GetName(type); | 411 std::string event_name = WebInputEvent::GetName(type); |
412 if (WebInputEvent::isKeyboardEventType(type)) | |
413 event_name = "KeyEvent"; | |
400 | 414 |
401 std::string default_action_status = | 415 std::string default_action_status = |
402 action_prevented ? "DefaultPrevented" : "DefaultAllowed"; | 416 action_prevented ? "DefaultPrevented" : "DefaultAllowed"; |
403 | 417 |
404 LatencyInfo::LatencyComponent main_component; | 418 LatencyInfo::LatencyComponent main_component; |
405 if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT, 0, | 419 if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_RENDERER_MAIN_COMPONENT, 0, |
406 &main_component)) { | 420 &main_component)) { |
407 DCHECK_EQ(main_component.event_count, 1u); | 421 DCHECK_EQ(main_component.event_count, 1u); |
408 if (!multi_finger_gesture_) { | 422 if (!multi_finger_gesture_) { |
mfomitchev
2017/04/04 14:59:05
Is it possible that a stale multi_finger_gesture_
tdresser
2017/05/01 15:49:21
Fixed in other patch, with follow up work here: cr
| |
409 UMA_HISTOGRAM_INPUT_LATENCY_MILLISECONDS( | 423 UMA_HISTOGRAM_INPUT_LATENCY_MILLISECONDS( |
410 "Event.Latency.QueueingTime." + event_name + default_action_status, | 424 "Event.Latency.QueueingTime." + event_name + default_action_status, |
411 rwh_component, main_component); | 425 rwh_component, main_component); |
412 } | 426 } |
413 } | 427 } |
414 | 428 |
415 LatencyInfo::LatencyComponent acked_component; | 429 LatencyInfo::LatencyComponent acked_component; |
416 if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0, | 430 if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0, |
417 &acked_component)) { | 431 &acked_component)) { |
418 DCHECK_EQ(acked_component.event_count, 1u); | 432 DCHECK_EQ(acked_component.event_count, 1u); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
461 0, | 475 0, |
462 0, | 476 0, |
463 timestamp_original, | 477 timestamp_original, |
464 1); | 478 1); |
465 } | 479 } |
466 | 480 |
467 latency->AddLatencyNumberWithTraceName( | 481 latency->AddLatencyNumberWithTraceName( |
468 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, latency_component_id_, | 482 ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, latency_component_id_, |
469 ++last_event_id_, WebInputEvent::GetName(event.type())); | 483 ++last_event_id_, WebInputEvent::GetName(event.type())); |
470 | 484 |
471 UpdateLatencyCoordinates(event, device_scale_factor_, latency); | 485 UpdateLatencyCoordinates(event, device_scale_factor_, latency); |
mfomitchev
2017/04/04 14:59:06
Does this make sense for key events?
tdresser
2017/05/01 15:49:21
Removed:
https://codereview.chromium.org/280469300
| |
472 | 486 |
473 if (event.type() == blink::WebInputEvent::GestureScrollBegin) { | 487 if (event.type() == blink::WebInputEvent::GestureScrollBegin) { |
474 has_seen_first_gesture_scroll_update_ = false; | 488 has_seen_first_gesture_scroll_update_ = false; |
475 } else if (event.type() == blink::WebInputEvent::GestureScrollUpdate) { | 489 } else if (event.type() == blink::WebInputEvent::GestureScrollUpdate) { |
476 // Make a copy of the INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT with a | 490 // Make a copy of the INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT with a |
477 // different name INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT. | 491 // different name INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT. |
478 // So we can track the latency specifically for scroll update events. | 492 // So we can track the latency specifically for scroll update events. |
479 LatencyInfo::LatencyComponent original_component; | 493 LatencyInfo::LatencyComponent original_component; |
480 if (latency->FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, | 494 if (latency->FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, |
481 &original_component)) { | 495 &original_component)) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
559 UMA_HISTOGRAM_TIMES("MPArch.RWH_TabSwitchPaintDuration", delta); | 573 UMA_HISTOGRAM_TIMES("MPArch.RWH_TabSwitchPaintDuration", delta); |
560 } | 574 } |
561 } | 575 } |
562 | 576 |
563 if (!latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, | 577 if (!latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, |
564 latency_component_id_, nullptr)) { | 578 latency_component_id_, nullptr)) { |
565 return; | 579 return; |
566 } | 580 } |
567 | 581 |
568 ui::SourceEventType source_event_type = latency.source_event_type(); | 582 ui::SourceEventType source_event_type = latency.source_event_type(); |
583 | |
569 if (source_event_type == ui::SourceEventType::WHEEL || | 584 if (source_event_type == ui::SourceEventType::WHEEL || |
570 source_event_type == ui::SourceEventType::TOUCH) { | 585 source_event_type == ui::SourceEventType::TOUCH || |
571 ComputeTouchAndWheelScrollLatencyHistograms( | 586 source_event_type == ui::SourceEventType::KEY) { |
587 ComputeEndToEndLatencyHistograms( | |
572 render_widget_host_delegate_, gpu_swap_begin_component, | 588 render_widget_host_delegate_, gpu_swap_begin_component, |
573 gpu_swap_end_component, latency_component_id_, latency); | 589 gpu_swap_end_component, latency_component_id_, latency); |
574 } | 590 } |
575 | 591 |
576 // Compute the old scroll update latency metrics. They are exclusively | 592 // Compute the old scroll update latency metrics. They are exclusively |
577 // calculated for touch scrolls, and will be deprecated on M56. | 593 // calculated for touch scrolls, and will be deprecated on M56. |
578 // (https://crbug.com/649754) | 594 // (https://crbug.com/649754) |
579 LatencyInfo::LatencyComponent mouse_wheel_scroll_update_component; | 595 LatencyInfo::LatencyComponent mouse_wheel_scroll_update_component; |
580 if (!latency.FindLatency( | 596 if (!latency.FindLatency( |
581 ui::INPUT_EVENT_LATENCY_GENERATE_SCROLL_UPDATE_FROM_MOUSE_WHEEL, 0, | 597 ui::INPUT_EVENT_LATENCY_GENERATE_SCROLL_UPDATE_FROM_MOUSE_WHEEL, 0, |
582 &mouse_wheel_scroll_update_component)) { | 598 &mouse_wheel_scroll_update_component)) { |
583 ComputeScrollLatencyHistograms(gpu_swap_begin_component, | 599 ComputeScrollLatencyHistograms(gpu_swap_begin_component, |
584 gpu_swap_end_component, | 600 gpu_swap_end_component, |
585 latency_component_id_, latency); | 601 latency_component_id_, latency); |
586 } | 602 } |
587 } | 603 } |
588 | 604 |
589 void RenderWidgetHostLatencyTracker::SetDelegate( | 605 void RenderWidgetHostLatencyTracker::SetDelegate( |
590 RenderWidgetHostDelegate* delegate) { | 606 RenderWidgetHostDelegate* delegate) { |
591 render_widget_host_delegate_ = delegate; | 607 render_widget_host_delegate_ = delegate; |
592 } | 608 } |
593 | 609 |
594 } // namespace content | 610 } // namespace content |
OLD | NEW |