| 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_functions.h" | 10 #include "base/metrics/histogram_functions.h" |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 base::UmaHistogramCustomCounts( \ | 90 base::UmaHistogramCustomCounts( \ |
| 91 name, (end.last_event_time - start.first_event_time).InMicroseconds(), \ | 91 name, (end.last_event_time - start.first_event_time).InMicroseconds(), \ |
| 92 1, 1000000, 100); | 92 1, 1000000, 100); |
| 93 | 93 |
| 94 #define UMA_HISTOGRAM_INPUT_LATENCY_MILLISECONDS(name, start, end) \ | 94 #define UMA_HISTOGRAM_INPUT_LATENCY_MILLISECONDS(name, start, end) \ |
| 95 CONFIRM_VALID_TIMING(start, end) \ | 95 CONFIRM_VALID_TIMING(start, end) \ |
| 96 base::UmaHistogramCustomCounts( \ | 96 base::UmaHistogramCustomCounts( \ |
| 97 name, (end.last_event_time - start.first_event_time).InMilliseconds(), \ | 97 name, (end.last_event_time - start.first_event_time).InMilliseconds(), \ |
| 98 1, 1000, 50); | 98 1, 1000, 50); |
| 99 | 99 |
| 100 // Touch/wheel to scroll latency using Rappor. | |
| 101 #define RAPPOR_TOUCH_WHEEL_TO_SCROLL_LATENCY(delegate, name, start, end) \ | |
| 102 CONFIRM_VALID_TIMING(start, end) \ | |
| 103 rappor::RapporService* rappor_service = \ | |
| 104 GetContentClient()->browser()->GetRapporService(); \ | |
| 105 if (rappor_service && delegate) { \ | |
| 106 std::unique_ptr<rappor::Sample> sample = \ | |
| 107 rappor_service->CreateSample(rappor::UMA_RAPPOR_TYPE); \ | |
| 108 delegate->AddDomainInfoToRapporSample(sample.get()); \ | |
| 109 sample->SetUInt64Field( \ | |
| 110 "Latency", \ | |
| 111 (end.last_event_time - start.first_event_time).InMicroseconds(), \ | |
| 112 rappor::NO_NOISE); \ | |
| 113 rappor_service->RecordSample(name, std::move(sample)); \ | |
| 114 } | |
| 115 | |
| 116 // Long touch/wheel scroll latency component that is mostly under 200ms. | 100 // Long touch/wheel scroll latency component that is mostly under 200ms. |
| 117 #define UMA_HISTOGRAM_SCROLL_LATENCY_LONG_2(name, start, end) \ | 101 #define UMA_HISTOGRAM_SCROLL_LATENCY_LONG_2(name, start, end) \ |
| 118 CONFIRM_VALID_TIMING(start, end) \ | 102 CONFIRM_VALID_TIMING(start, end) \ |
| 119 base::Histogram::FactoryGet(name, 1000, 200000, 50, \ | 103 base::Histogram::FactoryGet(name, 1000, 200000, 50, \ |
| 120 base::HistogramBase::kUmaTargetedHistogramFlag) \ | 104 base::HistogramBase::kUmaTargetedHistogramFlag) \ |
| 121 ->Add((end.last_event_time - start.first_event_time).InMicroseconds()); | 105 ->Add((end.last_event_time - start.first_event_time).InMicroseconds()); |
| 122 | 106 |
| 123 // Short touch/wheel scroll latency component that is mostly under 50ms. | 107 // Short touch/wheel scroll latency component that is mostly under 50ms. |
| 124 #define UMA_HISTOGRAM_SCROLL_LATENCY_SHORT_2(name, start, end) \ | 108 #define UMA_HISTOGRAM_SCROLL_LATENCY_SHORT_2(name, start, end) \ |
| 125 CONFIRM_VALID_TIMING(start, end) \ | 109 CONFIRM_VALID_TIMING(start, end) \ |
| 126 base::Histogram::FactoryGet(name, 1, 50000, 50, \ | 110 base::Histogram::FactoryGet(name, 1, 50000, 50, \ |
| 127 base::HistogramBase::kUmaTargetedHistogramFlag) \ | 111 base::HistogramBase::kUmaTargetedHistogramFlag) \ |
| 128 ->Add((end.last_event_time - start.first_event_time).InMicroseconds()); | 112 ->Add((end.last_event_time - start.first_event_time).InMicroseconds()); |
| 129 | 113 |
| 130 std::string LatencySourceEventTypeToInputModalityString( | |
| 131 ui::SourceEventType type) { | |
| 132 switch (type) { | |
| 133 case ui::SourceEventType::WHEEL: | |
| 134 return "Wheel"; | |
| 135 case ui::SourceEventType::TOUCH: | |
| 136 return "Touch"; | |
| 137 default: | |
| 138 return ""; | |
| 139 } | |
| 140 } | |
| 141 | |
| 142 std::string WebInputEventTypeToInputModalityString(WebInputEvent::Type type) { | 114 std::string WebInputEventTypeToInputModalityString(WebInputEvent::Type type) { |
| 143 if (type == blink::WebInputEvent::MouseWheel) { | 115 if (type == blink::WebInputEvent::MouseWheel) { |
| 144 return "Wheel"; | 116 return "Wheel"; |
| 145 } else if (WebInputEvent::isKeyboardEventType(type)) { | 117 } else if (WebInputEvent::isKeyboardEventType(type)) { |
| 146 return "Key"; | 118 return "Key"; |
| 147 } else if (WebInputEvent::isMouseEventType(type)) { | 119 } else if (WebInputEvent::isMouseEventType(type)) { |
| 148 return "Mouse"; | 120 return "Mouse"; |
| 149 } else if (WebInputEvent::isTouchEventType(type)) { | 121 } else if (WebInputEvent::isTouchEventType(type)) { |
| 150 return "Touch"; | 122 return "Touch"; |
| 151 } | 123 } |
| 152 return ""; | 124 return ""; |
| 153 } | 125 } |
| 154 | 126 |
| 155 void ComputeScrollLatencyHistograms( | |
| 156 const LatencyInfo::LatencyComponent& gpu_swap_begin_component, | |
| 157 const LatencyInfo::LatencyComponent& gpu_swap_end_component, | |
| 158 int64_t latency_component_id, | |
| 159 const LatencyInfo& latency, | |
| 160 bool is_running_navigation_hint_task) { | |
| 161 DCHECK(!latency.coalesced()); | |
| 162 if (latency.coalesced()) | |
| 163 return; | |
| 164 | |
| 165 DCHECK(!gpu_swap_begin_component.event_time.is_null()); | |
| 166 DCHECK(!gpu_swap_end_component.event_time.is_null()); | |
| 167 LatencyInfo::LatencyComponent original_component; | |
| 168 if (latency.FindLatency( | |
| 169 ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT, | |
| 170 latency_component_id, &original_component)) { | |
| 171 // This UMA metric tracks the time between the final frame swap for the | |
| 172 // first scroll event in a sequence and the original timestamp of that | |
| 173 // scroll event's underlying touch event. | |
| 174 for (size_t i = 0; i < original_component.event_count; i++) { | |
| 175 UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS( | |
| 176 "Event.Latency.TouchToFirstScrollUpdateSwapBegin", | |
| 177 original_component, gpu_swap_begin_component); | |
| 178 } | |
| 179 // TODO(horo): IsRunningNavigationHintTask UMAs are only for | |
| 180 // SpeculativeLaunchServiceWorker experimentation. So remove this UMA when | |
| 181 // the experimentation finished (crbug.com/638827). | |
| 182 if (is_running_navigation_hint_task) { | |
| 183 for (size_t i = 0; i < original_component.event_count; i++) { | |
| 184 UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS( | |
| 185 "Event.Latency.TouchToFirstScrollUpdateSwapBegin_" | |
| 186 "IsRunningNavigationHintTask", | |
| 187 original_component, gpu_swap_begin_component); | |
| 188 } | |
| 189 } | |
| 190 } else if (!latency.FindLatency( | |
| 191 ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT, | |
| 192 latency_component_id, &original_component)) { | |
| 193 return; | |
| 194 } | |
| 195 | |
| 196 // This UMA metric tracks the time from when the original touch event is | |
| 197 // created to when the scroll gesture results in final frame swap. | |
| 198 for (size_t i = 0; i < original_component.event_count; i++) { | |
| 199 UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS( | |
| 200 "Event.Latency.TouchToScrollUpdateSwapBegin", original_component, | |
| 201 gpu_swap_begin_component); | |
| 202 } | |
| 203 // TODO(horo): IsRunningNavigationHintTask UMAs are only for | |
| 204 // SpeculativeLaunchServiceWorker experimentation. So remove this UMA when | |
| 205 // the experimentation finished (crbug.com/638827). | |
| 206 if (is_running_navigation_hint_task) { | |
| 207 for (size_t i = 0; i < original_component.event_count; i++) { | |
| 208 UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS( | |
| 209 "Event.Latency.TouchToScrollUpdateSwapBegin_" | |
| 210 "IsRunningNavigationHintTask", | |
| 211 original_component, gpu_swap_begin_component); | |
| 212 } | |
| 213 } | |
| 214 } | |
| 215 | |
| 216 void ComputeTouchAndWheelScrollLatencyHistograms( | |
| 217 RenderWidgetHostDelegate* render_widget_host_delegate, | |
| 218 const ui::LatencyInfo::LatencyComponent& gpu_swap_begin_component, | |
| 219 const ui::LatencyInfo::LatencyComponent& gpu_swap_end_component, | |
| 220 int64_t latency_component_id, | |
| 221 const ui::LatencyInfo& latency) { | |
| 222 DCHECK(!latency.coalesced()); | |
| 223 if (latency.coalesced()) | |
| 224 return; | |
| 225 | |
| 226 LatencyInfo::LatencyComponent original_component; | |
| 227 std::string scroll_name = "ScrollUpdate"; | |
| 228 | |
| 229 const std::string input_modality = | |
| 230 LatencySourceEventTypeToInputModalityString(latency.source_event_type()); | |
| 231 | |
| 232 if (latency.FindLatency( | |
| 233 ui::INPUT_EVENT_LATENCY_FIRST_SCROLL_UPDATE_ORIGINAL_COMPONENT, | |
| 234 latency_component_id, &original_component)) { | |
| 235 scroll_name = "ScrollBegin"; | |
| 236 // This UMA metric tracks the time between the final frame swap for the | |
| 237 // first scroll event in a sequence and the original timestamp of that | |
| 238 // scroll event's underlying touch/wheel event. | |
| 239 UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS( | |
| 240 "Event.Latency.ScrollBegin." + input_modality + | |
| 241 ".TimeToScrollUpdateSwapBegin2", | |
| 242 original_component, gpu_swap_begin_component); | |
| 243 | |
| 244 RAPPOR_TOUCH_WHEEL_TO_SCROLL_LATENCY( | |
| 245 render_widget_host_delegate, | |
| 246 "Event.Latency.ScrollBegin." + input_modality + | |
| 247 ".TimeToScrollUpdateSwapBegin2", | |
| 248 original_component, gpu_swap_begin_component); | |
| 249 | |
| 250 // TODO(lanwei): Will remove them when M56 is stable, see | |
| 251 // https://crbug.com/669618. | |
| 252 UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS( | |
| 253 "Event.Latency.ScrollUpdate." + input_modality + | |
| 254 ".TimeToFirstScrollUpdateSwapBegin2", | |
| 255 original_component, gpu_swap_begin_component); | |
| 256 } else if (latency.FindLatency( | |
| 257 ui::INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL_COMPONENT, | |
| 258 latency_component_id, &original_component)) { | |
| 259 // This UMA metric tracks the time from when the original touch event is | |
| 260 // created to when the scroll gesture results in final frame swap. | |
| 261 // First scroll events are excluded from this metric. | |
| 262 if (input_modality == "Touch") { | |
| 263 UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS( | |
| 264 "Event.Latency.ScrollUpdate.Touch.TimeToScrollUpdateSwapBegin2", | |
| 265 original_component, gpu_swap_begin_component); | |
| 266 | |
| 267 RAPPOR_TOUCH_WHEEL_TO_SCROLL_LATENCY( | |
| 268 render_widget_host_delegate, | |
| 269 "Event.Latency.ScrollUpdate.Touch.TimeToScrollUpdateSwapBegin2", | |
| 270 original_component, gpu_swap_begin_component); | |
| 271 } | |
| 272 } else { | |
| 273 // No original component found. | |
| 274 return; | |
| 275 } | |
| 276 | |
| 277 LatencyInfo::LatencyComponent rendering_scheduled_component; | |
| 278 bool rendering_scheduled_on_main = latency.FindLatency( | |
| 279 ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_MAIN_COMPONENT, 0, | |
| 280 &rendering_scheduled_component); | |
| 281 if (!rendering_scheduled_on_main) { | |
| 282 if (!latency.FindLatency( | |
| 283 ui::INPUT_EVENT_LATENCY_RENDERING_SCHEDULED_IMPL_COMPONENT, 0, | |
| 284 &rendering_scheduled_component)) | |
| 285 return; | |
| 286 } | |
| 287 | |
| 288 const std::string thread_name = rendering_scheduled_on_main ? "Main" : "Impl"; | |
| 289 | |
| 290 UMA_HISTOGRAM_SCROLL_LATENCY_LONG_2( | |
| 291 "Event.Latency." + scroll_name + "." + input_modality + | |
| 292 ".TimeToHandled2_" + thread_name, | |
| 293 original_component, rendering_scheduled_component); | |
| 294 | |
| 295 LatencyInfo::LatencyComponent renderer_swap_component; | |
| 296 if (!latency.FindLatency(ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, 0, | |
| 297 &renderer_swap_component)) | |
| 298 return; | |
| 299 | |
| 300 UMA_HISTOGRAM_SCROLL_LATENCY_LONG_2( | |
| 301 "Event.Latency." + scroll_name + "." + input_modality + | |
| 302 ".HandledToRendererSwap2_" + thread_name, | |
| 303 rendering_scheduled_component, renderer_swap_component); | |
| 304 | |
| 305 LatencyInfo::LatencyComponent browser_received_swap_component; | |
| 306 if (!latency.FindLatency( | |
| 307 ui::INPUT_EVENT_BROWSER_RECEIVED_RENDERER_SWAP_COMPONENT, 0, | |
| 308 &browser_received_swap_component)) | |
| 309 return; | |
| 310 | |
| 311 UMA_HISTOGRAM_SCROLL_LATENCY_SHORT_2( | |
| 312 "Event.Latency." + scroll_name + "." + input_modality + | |
| 313 ".RendererSwapToBrowserNotified2", | |
| 314 renderer_swap_component, browser_received_swap_component); | |
| 315 | |
| 316 UMA_HISTOGRAM_SCROLL_LATENCY_LONG_2( | |
| 317 "Event.Latency." + scroll_name + "." + input_modality + | |
| 318 ".BrowserNotifiedToBeforeGpuSwap2", | |
| 319 browser_received_swap_component, gpu_swap_begin_component); | |
| 320 | |
| 321 UMA_HISTOGRAM_SCROLL_LATENCY_SHORT_2( | |
| 322 "Event.Latency." + scroll_name + "." + input_modality + ".GpuSwap2", | |
| 323 gpu_swap_begin_component, gpu_swap_end_component); | |
| 324 } | |
| 325 // LatencyComponents generated in the renderer must have component IDs | 127 // LatencyComponents generated in the renderer must have component IDs |
| 326 // provided to them by the browser process. This function adds the correct | 128 // provided to them by the browser process. This function adds the correct |
| 327 // component ID where necessary. | 129 // component ID where necessary. |
| 328 void AddLatencyInfoComponentIds(LatencyInfo* latency, | 130 void AddLatencyInfoComponentIds(LatencyInfo* latency, |
| 329 int64_t latency_component_id) { | 131 int64_t latency_component_id) { |
| 330 std::vector<std::pair<ui::LatencyComponentType, int64_t>> new_components_key; | 132 std::vector<std::pair<ui::LatencyComponentType, int64_t>> new_components_key; |
| 331 std::vector<LatencyInfo::LatencyComponent> new_components_value; | 133 std::vector<LatencyInfo::LatencyComponent> new_components_value; |
| 332 for (const auto& lc : latency->latency_components()) { | 134 for (const auto& lc : latency->latency_components()) { |
| 333 ui::LatencyComponentType component_type = lc.first.first; | 135 ui::LatencyComponentType component_type = lc.first.first; |
| 334 if (component_type == ui::WINDOW_SNAPSHOT_FRAME_NUMBER_COMPONENT) { | 136 if (component_type == ui::WINDOW_SNAPSHOT_FRAME_NUMBER_COMPONENT) { |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS( | 253 UMA_HISTOGRAM_INPUT_LATENCY_HIGH_RESOLUTION_MICROSECONDS( |
| 452 "Event.Latency.Browser." + input_modality + "Acked", rwh_component, | 254 "Event.Latency.Browser." + input_modality + "Acked", rwh_component, |
| 453 acked_component); | 255 acked_component); |
| 454 } | 256 } |
| 455 } | 257 } |
| 456 } | 258 } |
| 457 | 259 |
| 458 void RenderWidgetHostLatencyTracker::OnInputEvent( | 260 void RenderWidgetHostLatencyTracker::OnInputEvent( |
| 459 const blink::WebInputEvent& event, | 261 const blink::WebInputEvent& event, |
| 460 LatencyInfo* latency) { | 262 LatencyInfo* latency) { |
| 263 |
| 461 DCHECK(latency); | 264 DCHECK(latency); |
| 462 if (latency->FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, | 265 if (latency->FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, |
| 463 latency_component_id_, NULL)) { | 266 latency_component_id_, NULL)) { |
| 464 return; | 267 return; |
| 465 } | 268 } |
| 466 | 269 |
| 467 if (event.timeStampSeconds() && | 270 if (event.timeStampSeconds() && |
| 468 !latency->FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, | 271 !latency->FindLatency(ui::INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT, 0, |
| 469 NULL)) { | 272 NULL)) { |
| 470 base::TimeTicks timestamp_now = base::TimeTicks::Now(); | 273 base::TimeTicks timestamp_now = base::TimeTicks::Now(); |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 554 for (LatencyInfo& latency : *latencies) { | 357 for (LatencyInfo& latency : *latencies) { |
| 555 AddLatencyInfoComponentIds(&latency, latency_component_id_); | 358 AddLatencyInfoComponentIds(&latency, latency_component_id_); |
| 556 latency.AddLatencyNumber( | 359 latency.AddLatencyNumber( |
| 557 ui::INPUT_EVENT_BROWSER_RECEIVED_RENDERER_SWAP_COMPONENT, 0, 0); | 360 ui::INPUT_EVENT_BROWSER_RECEIVED_RENDERER_SWAP_COMPONENT, 0, 0); |
| 558 } | 361 } |
| 559 } | 362 } |
| 560 | 363 |
| 561 void RenderWidgetHostLatencyTracker::OnFrameSwapped( | 364 void RenderWidgetHostLatencyTracker::OnFrameSwapped( |
| 562 const LatencyInfo& latency, | 365 const LatencyInfo& latency, |
| 563 bool is_running_navigation_hint_task) { | 366 bool is_running_navigation_hint_task) { |
| 564 LatencyInfo::LatencyComponent gpu_swap_end_component; | 367 OnGpuSwapBufersCompleted(latency, is_running_navigation_hint_task); |
| 565 if (!latency.FindLatency( | |
| 566 ui::INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT, 0, | |
| 567 &gpu_swap_end_component)) { | |
| 568 return; | |
| 569 } | |
| 570 | 368 |
| 571 LatencyInfo::LatencyComponent gpu_swap_begin_component; | |
| 572 if (!latency.FindLatency(ui::INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT, 0, | |
| 573 &gpu_swap_begin_component)) { | |
| 574 return; | |
| 575 } | |
| 576 | |
| 577 LatencyInfo::LatencyComponent tab_switch_component; | |
| 578 if (latency.FindLatency(ui::TAB_SHOW_COMPONENT, latency_component_id_, | |
| 579 &tab_switch_component)) { | |
| 580 base::TimeDelta delta = | |
| 581 gpu_swap_end_component.event_time - tab_switch_component.event_time; | |
| 582 for (size_t i = 0; i < tab_switch_component.event_count; i++) { | |
| 583 UMA_HISTOGRAM_TIMES("MPArch.RWH_TabSwitchPaintDuration", delta); | |
| 584 } | |
| 585 } | |
| 586 | |
| 587 if (!latency.FindLatency(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, | |
| 588 latency_component_id_, nullptr)) { | |
| 589 return; | |
| 590 } | |
| 591 | |
| 592 ui::SourceEventType source_event_type = latency.source_event_type(); | |
| 593 if (source_event_type == ui::SourceEventType::WHEEL || | |
| 594 source_event_type == ui::SourceEventType::TOUCH) { | |
| 595 ComputeTouchAndWheelScrollLatencyHistograms( | |
| 596 render_widget_host_delegate_, gpu_swap_begin_component, | |
| 597 gpu_swap_end_component, latency_component_id_, latency); | |
| 598 } | |
| 599 | |
| 600 // Compute the old scroll update latency metrics. They are exclusively | |
| 601 // calculated for touch scrolls, and will be deprecated on M56. | |
| 602 // (https://crbug.com/649754) | |
| 603 LatencyInfo::LatencyComponent mouse_wheel_scroll_update_component; | |
| 604 if (!latency.FindLatency( | |
| 605 ui::INPUT_EVENT_LATENCY_GENERATE_SCROLL_UPDATE_FROM_MOUSE_WHEEL, 0, | |
| 606 &mouse_wheel_scroll_update_component)) { | |
| 607 ComputeScrollLatencyHistograms( | |
| 608 gpu_swap_begin_component, gpu_swap_end_component, latency_component_id_, | |
| 609 latency, is_running_navigation_hint_task); | |
| 610 } | |
| 611 } | 369 } |
| 612 | 370 |
| 613 void RenderWidgetHostLatencyTracker::SetDelegate( | 371 void RenderWidgetHostLatencyTracker::SetDelegate( |
| 614 RenderWidgetHostDelegate* delegate) { | 372 RenderWidgetHostDelegate* delegate) { |
| 615 render_widget_host_delegate_ = delegate; | 373 render_widget_host_delegate_ = delegate; |
| 616 } | 374 } |
| 617 | 375 |
| 376 void RenderWidgetHostLatencyTracker::ReportRapporScrollLatency( |
| 377 const std::string& name, |
| 378 const LatencyInfo::LatencyComponent& start_component, |
| 379 const LatencyInfo::LatencyComponent& end_component) { |
| 380 CONFIRM_VALID_TIMING(start_component, end_component) |
| 381 rappor::RapporService* rappor_service = |
| 382 GetContentClient()->browser()->GetRapporService(); |
| 383 if (rappor_service && render_widget_host_delegate_) { |
| 384 std::unique_ptr<rappor::Sample> sample = |
| 385 rappor_service->CreateSample(rappor::UMA_RAPPOR_TYPE); |
| 386 render_widget_host_delegate_->AddDomainInfoToRapporSample(sample.get()); |
| 387 sample->SetUInt64Field( |
| 388 "Latency", |
| 389 (end_component.last_event_time - start_component.first_event_time).InMic
roseconds(), |
| 390 rappor::NO_NOISE); |
| 391 rappor_service->RecordSample(name, std::move(sample)); |
| 392 } |
| 393 } |
| 394 |
| 618 } // namespace content | 395 } // namespace content |
| OLD | NEW |