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

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

Issue 1861733002: Add touch drag UMA latency metric. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Actually fix tests. Created 4 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 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.h" 10 #include "base/metrics/histogram.h"
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 latency, device_scale_factor); 68 latency, device_scale_factor);
69 } else if (WebInputEvent::isTouchEventType(event.type)) { 69 } else if (WebInputEvent::isTouchEventType(event.type)) {
70 UpdateLatencyCoordinatesImpl(static_cast<const WebTouchEvent&>(event), 70 UpdateLatencyCoordinatesImpl(static_cast<const WebTouchEvent&>(event),
71 latency, device_scale_factor); 71 latency, device_scale_factor);
72 } else if (event.type == WebInputEvent::MouseWheel) { 72 } else if (event.type == WebInputEvent::MouseWheel) {
73 UpdateLatencyCoordinatesImpl(static_cast<const WebMouseWheelEvent&>(event), 73 UpdateLatencyCoordinatesImpl(static_cast<const WebMouseWheelEvent&>(event),
74 latency, device_scale_factor); 74 latency, device_scale_factor);
75 } 75 }
76 } 76 }
77 77
78 void ComputeInputLatencyHistograms(WebInputEvent::Type type,
79 int64_t latency_component_id,
80 const LatencyInfo& latency) {
81 if (latency.coalesced())
82 return;
83
84 LatencyInfo::LatencyComponent rwh_component;
85 if (!latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
86 latency_component_id, &rwh_component)) {
87 return;
88 }
89 DCHECK_EQ(rwh_component.event_count, 1u);
90
91 LatencyInfo::LatencyComponent ui_component;
92 if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0,
93 &ui_component)) {
94 DCHECK_EQ(ui_component.event_count, 1u);
95 base::TimeDelta ui_delta =
96 rwh_component.event_time - ui_component.event_time;
97 switch (type) {
98 case blink::WebInputEvent::MouseWheel:
99 UMA_HISTOGRAM_CUSTOM_COUNTS(
100 "Event.Latency.Browser.WheelUI",
101 ui_delta.InMicroseconds(), 1, 20000, 100);
102 break;
103 case blink::WebInputEvent::TouchTypeFirst:
104 UMA_HISTOGRAM_CUSTOM_COUNTS(
105 "Event.Latency.Browser.TouchUI",
106 ui_delta.InMicroseconds(), 1, 20000, 100);
107 break;
108 default:
109 NOTREACHED();
110 break;
111 }
112 }
113
114 LatencyInfo::LatencyComponent acked_component;
115 if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0,
116 &acked_component)) {
117 DCHECK_EQ(acked_component.event_count, 1u);
118 base::TimeDelta acked_delta =
119 acked_component.event_time - rwh_component.event_time;
120 switch (type) {
121 case blink::WebInputEvent::MouseWheel:
122 UMA_HISTOGRAM_CUSTOM_COUNTS(
123 "Event.Latency.Browser.WheelAcked",
124 acked_delta.InMicroseconds(), 1, 1000000, 100);
125 break;
126 case blink::WebInputEvent::TouchTypeFirst:
127 UMA_HISTOGRAM_CUSTOM_COUNTS(
128 "Event.Latency.Browser.TouchAcked",
129 acked_delta.InMicroseconds(), 1, 1000000, 100);
130 break;
131 default:
132 NOTREACHED();
133 break;
134 }
135 }
136 }
137
138 // Touch to scroll latency that is mostly under 1 second. 78 // Touch to scroll latency that is mostly under 1 second.
139 #define UMA_HISTOGRAM_TOUCH_TO_SCROLL_LATENCY(name, start, end) \ 79 #define UMA_HISTOGRAM_TOUCH_TO_SCROLL_LATENCY(name, start, end) \
140 UMA_HISTOGRAM_CUSTOM_COUNTS( \ 80 UMA_HISTOGRAM_CUSTOM_COUNTS( \
141 name, (end.event_time - start.event_time).InMicroseconds(), 1, 1000000, \ 81 name, (end.event_time - start.event_time).InMicroseconds(), 1, 1000000, \
142 100) 82 100)
143 83
144 // Long scroll latency component that is mostly under 200ms. 84 // Long scroll latency component that is mostly under 200ms.
145 #define UMA_HISTOGRAM_SCROLL_LATENCY_LONG(name, start, end) \ 85 #define UMA_HISTOGRAM_SCROLL_LATENCY_LONG(name, start, end) \
146 UMA_HISTOGRAM_CUSTOM_COUNTS( \ 86 UMA_HISTOGRAM_CUSTOM_COUNTS( \
147 name, \ 87 name, \
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 new_components_value[i].event_count); 220 new_components_value[i].event_count);
281 } 221 }
282 } 222 }
283 223
284 } // namespace 224 } // namespace
285 225
286 RenderWidgetHostLatencyTracker::RenderWidgetHostLatencyTracker() 226 RenderWidgetHostLatencyTracker::RenderWidgetHostLatencyTracker()
287 : last_event_id_(0), 227 : last_event_id_(0),
288 latency_component_id_(0), 228 latency_component_id_(0),
289 device_scale_factor_(1), 229 device_scale_factor_(1),
290 has_seen_first_gesture_scroll_update_(false) { 230 has_seen_first_gesture_scroll_update_(false),
291 } 231 multi_finger_gesture_(false),
232 touch_start_default_prevented_(false) {}
292 233
293 RenderWidgetHostLatencyTracker::~RenderWidgetHostLatencyTracker() { 234 RenderWidgetHostLatencyTracker::~RenderWidgetHostLatencyTracker() {}
294 }
295 235
296 void RenderWidgetHostLatencyTracker::Initialize(int routing_id, 236 void RenderWidgetHostLatencyTracker::Initialize(int routing_id,
297 int process_id) { 237 int process_id) {
298 DCHECK_EQ(0, last_event_id_); 238 DCHECK_EQ(0, last_event_id_);
299 DCHECK_EQ(0, latency_component_id_); 239 DCHECK_EQ(0, latency_component_id_);
300 last_event_id_ = static_cast<int64_t>(process_id) << 32; 240 last_event_id_ = static_cast<int64_t>(process_id) << 32;
301 latency_component_id_ = routing_id | last_event_id_; 241 latency_component_id_ = routing_id | last_event_id_;
302 } 242 }
303 243
244 void RenderWidgetHostLatencyTracker::ComputeInputLatencyHistograms(
245 WebInputEvent::Type type,
246 int64_t latency_component_id,
247 const LatencyInfo& latency,
248 bool default_prevented) {
249 if (latency.coalesced())
250 return;
251
252 LatencyInfo::LatencyComponent rwh_component;
253 if (!latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
254 latency_component_id, &rwh_component)) {
255 return;
256 }
257 DCHECK_EQ(rwh_component.event_count, 1u);
258
259 LatencyInfo::LatencyComponent ui_component;
260 if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_UI_COMPONENT, 0,
261 &ui_component)) {
262 DCHECK_EQ(ui_component.event_count, 1u);
263 base::TimeDelta ui_delta =
264 rwh_component.event_time - ui_component.event_time;
265
266 if (type == blink::WebInputEvent::MouseWheel) {
267 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.Browser.WheelUI",
268 ui_delta.InMicroseconds(), 1, 20000, 100);
269
270 } else {
271 DCHECK(WebInputEvent::isTouchEventType(type));
272 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.Browser.TouchUI",
273 ui_delta.InMicroseconds(), 1, 20000, 100);
274 }
275 }
276
277 LatencyInfo::LatencyComponent dispatched_to_renderer_component;
278 if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_REACHED_RWH_COMPONENT, 0,
279 &dispatched_to_renderer_component)) {
280 DCHECK_EQ(dispatched_to_renderer_component.event_count, 1u);
281 base::TimeDelta queueing_delta =
282 dispatched_to_renderer_component.event_time - rwh_component.event_time;
283 if (type == WebInputEvent::TouchMove && !multi_finger_gesture_) {
284 if (touch_start_default_prevented_ || default_prevented) {
285 UMA_HISTOGRAM_CUSTOM_COUNTS(
286 "Event.Latency.QueueingTime.TouchMoveDefaultPrevented",
287 queueing_delta.InMicroseconds(), 1, 1000000, 100);
288 } else {
289 UMA_HISTOGRAM_CUSTOM_COUNTS(
290 "Event.Latency.QueueingTime.TouchMoveDefaultAllowed",
291 queueing_delta.InMicroseconds(), 1, 1000000, 100);
292 }
293 }
294 }
295
296 LatencyInfo::LatencyComponent acked_component;
297 if (latency.FindLatency(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0,
298 &acked_component)) {
299 DCHECK_EQ(acked_component.event_count, 1u);
300 base::TimeDelta acked_delta =
301 acked_component.event_time - rwh_component.event_time;
302 if (type == blink::WebInputEvent::MouseWheel) {
303 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.Browser.WheelAcked",
304 acked_delta.InMicroseconds(), 1, 1000000,
305 100);
306 } else {
307 DCHECK(WebInputEvent::isTouchEventType(type));
308 UMA_HISTOGRAM_CUSTOM_COUNTS("Event.Latency.Browser.TouchAcked",
309 acked_delta.InMicroseconds(), 1, 1000000,
310 100);
311 }
312
313 if (type == WebInputEvent::TouchMove && !multi_finger_gesture_) {
314 base::TimeDelta blocking_delta;
315 if (dispatched_to_renderer_component.event_time != base::TimeTicks()) {
316 blocking_delta = acked_component.event_time -
317 dispatched_to_renderer_component.event_time;
318 }
319
320 if (touch_start_default_prevented_ || default_prevented) {
321 UMA_HISTOGRAM_CUSTOM_COUNTS(
322 "Event.Latency.BlockingTime.TouchMoveDefaultPrevented",
323 blocking_delta.InMicroseconds(), 1, 1000000, 100);
324 } else {
325 UMA_HISTOGRAM_CUSTOM_COUNTS(
326 "Event.Latency.BlockingTime.TouchMoveDefaultAllowed",
327 blocking_delta.InMicroseconds(), 1, 1000000, 100);
Ilya Sherman 2016/04/06 01:34:54 Do you need 100 buckets, or would 50 suffice?
tdresser 2016/05/19 20:48:08 Done.
328 }
329 }
330 }
331 }
332
304 void RenderWidgetHostLatencyTracker::OnInputEvent( 333 void RenderWidgetHostLatencyTracker::OnInputEvent(
305 const blink::WebInputEvent& event, 334 const blink::WebInputEvent& event,
306 LatencyInfo* latency) { 335 LatencyInfo* latency) {
307 DCHECK(latency); 336 DCHECK(latency);
308 if (latency->FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, 337 if (latency->FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT,
309 latency_component_id_, NULL)) { 338 latency_component_id_, NULL)) {
310 return; 339 return;
311 } 340 }
312 341
313 if (event.timeStampSeconds && 342 if (event.timeStampSeconds &&
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
353 ? ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT 382 ? ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT
354 : ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT, 383 : ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT,
355 latency_component_id_, original_component.sequence_number, 384 latency_component_id_, original_component.sequence_number,
356 original_component.event_time, original_component.event_count); 385 original_component.event_time, original_component.event_count);
357 } 386 }
358 387
359 has_seen_first_gesture_scroll_update_ = true; 388 has_seen_first_gesture_scroll_update_ = true;
360 } 389 }
361 } 390 }
362 391
392 void RenderWidgetHostLatencyTracker::OnForwardEventToRenderer(
393 const blink::WebInputEvent& event,
394 ui::LatencyInfo* latency) {
395 DCHECK(latency);
396 if (WebInputEvent::isTouchEventType(event.type)) {
397 latency->AddLatencyNumber(ui::INPUT_EVENT_LATENCY_REACHED_RWH_COMPONENT, 0,
398 0);
399 }
400 }
401
363 void RenderWidgetHostLatencyTracker::OnInputEventAck( 402 void RenderWidgetHostLatencyTracker::OnInputEventAck(
364 const blink::WebInputEvent& event, 403 const blink::WebInputEvent& event,
365 LatencyInfo* latency) { 404 LatencyInfo* latency, bool defaultPrevented) {
366 DCHECK(latency); 405 DCHECK(latency);
367 406
368 // Latency ends when it is acked but does not cause render scheduling. 407 // Latency ends when it is acked but does not cause render scheduling.
369 bool rendering_scheduled = latency->FindLatency( 408 bool rendering_scheduled = latency->FindLatency(
370 ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN_COMPONENT, 0, nullptr); 409 ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN_COMPONENT, 0, nullptr);
371 rendering_scheduled |= latency->FindLatency( 410 rendering_scheduled |= latency->FindLatency(
372 ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL_COMPONENT, 0, nullptr); 411 ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL_COMPONENT, 0, nullptr);
373 412
374 if (WebInputEvent::isGestureEventType(event.type)) { 413 if (WebInputEvent::isGestureEventType(event.type)) {
375 if (!rendering_scheduled) { 414 if (!rendering_scheduled) {
376 latency->AddLatencyNumber( 415 latency->AddLatencyNumber(
377 ui::INPUT_EVENT_LATENCY_TERMINATED_GESTURE_COMPONENT, 0, 0); 416 ui::INPUT_EVENT_LATENCY_TERMINATED_GESTURE_COMPONENT, 0, 0);
378 // TODO(jdduke): Consider exposing histograms for gesture event types. 417 // TODO(jdduke): Consider exposing histograms for gesture event types.
379 } 418 }
380 return; 419 return;
381 } 420 }
382 421
383 if (WebInputEvent::isTouchEventType(event.type)) { 422 if (WebInputEvent::isTouchEventType(event.type)) {
423 const WebTouchEvent& touch_event =
424 *static_cast<const WebTouchEvent*>(&event);
425 if (event.type == WebInputEvent::TouchStart) {
426 DCHECK(touch_event.touchesLength >= 1);
427 multi_finger_gesture_ = touch_event.touchesLength != 1;
428 touch_start_default_prevented_ = defaultPrevented;
429 }
430
384 latency->AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0, 0); 431 latency->AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0, 0);
432
385 if (!rendering_scheduled) { 433 if (!rendering_scheduled) {
386 latency->AddLatencyNumber( 434 latency->AddLatencyNumber(
387 ui::INPUT_EVENT_LATENCY_TERMINATED_TOUCH_COMPONENT, 0, 0); 435 ui::INPUT_EVENT_LATENCY_TERMINATED_TOUCH_COMPONENT, 0, 0);
388 } 436 }
389 ComputeInputLatencyHistograms(WebInputEvent::TouchTypeFirst, 437 ComputeInputLatencyHistograms(event.type, latency_component_id_, *latency,
390 latency_component_id_, *latency); 438 defaultPrevented);
391 return; 439 return;
392 } 440 }
393 441
394 if (event.type == WebInputEvent::MouseWheel) { 442 if (event.type == WebInputEvent::MouseWheel) {
395 latency->AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0, 0); 443 latency->AddLatencyNumber(ui::INPUT_EVENT_LATENCY_ACK_RWH_COMPONENT, 0, 0);
396 if (!rendering_scheduled) { 444 if (!rendering_scheduled) {
397 latency->AddLatencyNumber( 445 latency->AddLatencyNumber(
398 ui::INPUT_EVENT_LATENCY_TERMINATED_MOUSE_WHEEL_COMPONENT, 0, 0); 446 ui::INPUT_EVENT_LATENCY_TERMINATED_MOUSE_WHEEL_COMPONENT, 0, 0);
399 } 447 }
400 ComputeInputLatencyHistograms(WebInputEvent::MouseWheel, 448 ComputeInputLatencyHistograms(event.type, latency_component_id_, *latency,
401 latency_component_id_, *latency); 449 defaultPrevented);
402 return; 450 return;
403 } 451 }
404 452
405 if (WebInputEvent::isMouseEventType(event.type) && !rendering_scheduled) { 453 if (WebInputEvent::isMouseEventType(event.type) && !rendering_scheduled) {
406 latency->AddLatencyNumber( 454 latency->AddLatencyNumber(
407 ui::INPUT_EVENT_LATENCY_TERMINATED_MOUSE_COMPONENT, 0, 0); 455 ui::INPUT_EVENT_LATENCY_TERMINATED_MOUSE_COMPONENT, 0, 0);
408 return; 456 return;
409 } 457 }
410 458
411 if (WebInputEvent::isKeyboardEventType(event.type) && !rendering_scheduled) { 459 if (WebInputEvent::isKeyboardEventType(event.type) && !rendering_scheduled) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 latency_component_id_, nullptr)) { 502 latency_component_id_, nullptr)) {
455 return; 503 return;
456 } 504 }
457 505
458 ComputeScrollLatencyHistograms(gpu_swap_begin_component, 506 ComputeScrollLatencyHistograms(gpu_swap_begin_component,
459 gpu_swap_end_component, latency_component_id_, 507 gpu_swap_end_component, latency_component_id_,
460 latency); 508 latency);
461 } 509 }
462 510
463 } // namespace content 511 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698