| 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 "cc/scheduler/compositor_timing_history.h" | 5 #include "cc/scheduler/compositor_timing_history.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include "base/memory/ptr_util.h" | 10 #include "base/memory/ptr_util.h" |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 base::TimeDelta duration) = 0; | 30 base::TimeDelta duration) = 0; |
| 31 virtual void AddBeginMainFrameQueueDurationNotCriticalDuration( | 31 virtual void AddBeginMainFrameQueueDurationNotCriticalDuration( |
| 32 base::TimeDelta duration) = 0; | 32 base::TimeDelta duration) = 0; |
| 33 virtual void AddBeginMainFrameStartToCommitDuration( | 33 virtual void AddBeginMainFrameStartToCommitDuration( |
| 34 base::TimeDelta duration) = 0; | 34 base::TimeDelta duration) = 0; |
| 35 virtual void AddCommitToReadyToActivateDuration(base::TimeDelta duration) = 0; | 35 virtual void AddCommitToReadyToActivateDuration(base::TimeDelta duration) = 0; |
| 36 virtual void AddPrepareTilesDuration(base::TimeDelta duration) = 0; | 36 virtual void AddPrepareTilesDuration(base::TimeDelta duration) = 0; |
| 37 virtual void AddActivateDuration(base::TimeDelta duration) = 0; | 37 virtual void AddActivateDuration(base::TimeDelta duration) = 0; |
| 38 virtual void AddDrawDuration(base::TimeDelta duration) = 0; | 38 virtual void AddDrawDuration(base::TimeDelta duration) = 0; |
| 39 virtual void AddSwapToAckLatency(base::TimeDelta duration) = 0; | 39 virtual void AddSwapToAckLatency(base::TimeDelta duration) = 0; |
| 40 virtual void AddSwapAckWasFast(bool was_fast) = 0; |
| 40 | 41 |
| 41 // Synchronization measurements | 42 // Synchronization measurements |
| 42 virtual void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) = 0; | 43 virtual void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) = 0; |
| 43 }; | 44 }; |
| 44 | 45 |
| 45 namespace { | 46 namespace { |
| 46 | 47 |
| 47 // Using the 90th percentile will disable latency recovery | 48 // Using the 90th percentile will disable latency recovery |
| 48 // if we are missing the deadline approximately ~6 times per | 49 // if we are missing the deadline approximately ~6 times per |
| 49 // second. | 50 // second. |
| 50 // TODO(brianderson): Fine tune the percentiles below. | 51 // TODO(brianderson): Fine tune the percentiles below. |
| 51 const size_t kDurationHistorySize = 60; | 52 const size_t kDurationHistorySize = 60; |
| 52 const double kBeginMainFrameQueueDurationEstimationPercentile = 90.0; | 53 const double kBeginMainFrameQueueDurationEstimationPercentile = 90.0; |
| 53 const double kBeginMainFrameQueueDurationCriticalEstimationPercentile = 90.0; | 54 const double kBeginMainFrameQueueDurationCriticalEstimationPercentile = 90.0; |
| 54 const double kBeginMainFrameQueueDurationNotCriticalEstimationPercentile = 90.0; | 55 const double kBeginMainFrameQueueDurationNotCriticalEstimationPercentile = 90.0; |
| 55 const double kBeginMainFrameStartToCommitEstimationPercentile = 90.0; | 56 const double kBeginMainFrameStartToCommitEstimationPercentile = 90.0; |
| 56 const double kCommitToReadyToActivateEstimationPercentile = 90.0; | 57 const double kCommitToReadyToActivateEstimationPercentile = 90.0; |
| 57 const double kPrepareTilesEstimationPercentile = 90.0; | 58 const double kPrepareTilesEstimationPercentile = 90.0; |
| 58 const double kActivateEstimationPercentile = 90.0; | 59 const double kActivateEstimationPercentile = 90.0; |
| 59 const double kDrawEstimationPercentile = 90.0; | 60 const double kDrawEstimationPercentile = 90.0; |
| 60 | 61 |
| 62 constexpr base::TimeDelta kSwapAckWatchdogTimeout = |
| 63 base::TimeDelta::FromSeconds(8); |
| 64 |
| 61 const int kUmaDurationMinMicros = 1; | 65 const int kUmaDurationMinMicros = 1; |
| 62 const int64_t kUmaDurationMaxMicros = base::Time::kMicrosecondsPerSecond / 5; | 66 const int64_t kUmaDurationMaxMicros = base::Time::kMicrosecondsPerSecond / 5; |
| 63 const int kUmaDurationBucketCount = 100; | 67 const int kUmaDurationBucketCount = 100; |
| 64 | 68 |
| 65 // This macro is deprecated since its bucket count uses too much bandwidth. | 69 // This macro is deprecated since its bucket count uses too much bandwidth. |
| 66 // It also has sub-optimal range and bucket distribution. | 70 // It also has sub-optimal range and bucket distribution. |
| 67 // TODO(brianderson): Delete this macro and associated UMAs once there is | 71 // TODO(brianderson): Delete this macro and associated UMAs once there is |
| 68 // sufficient overlap with the re-bucketed UMAs. | 72 // sufficient overlap with the re-bucketed UMAs. |
| 69 #define UMA_HISTOGRAM_CUSTOM_TIMES_MICROS(name, sample) \ | 73 #define UMA_HISTOGRAM_CUSTOM_TIMES_MICROS(name, sample) \ |
| 70 UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample.InMicroseconds(), \ | 74 UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample.InMicroseconds(), \ |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 void AddDrawDuration(base::TimeDelta duration) override { | 188 void AddDrawDuration(base::TimeDelta duration) override { |
| 185 UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Renderer.DrawDuration", | 189 UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Renderer.DrawDuration", |
| 186 duration); | 190 duration); |
| 187 } | 191 } |
| 188 | 192 |
| 189 void AddSwapToAckLatency(base::TimeDelta duration) override { | 193 void AddSwapToAckLatency(base::TimeDelta duration) override { |
| 190 UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Renderer.SwapToAckLatency", | 194 UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Renderer.SwapToAckLatency", |
| 191 duration); | 195 duration); |
| 192 } | 196 } |
| 193 | 197 |
| 198 void AddSwapAckWasFast(bool was_fast) override { |
| 199 UMA_HISTOGRAM_BOOLEAN("Scheduling.Renderer.SwapAckWasFast", was_fast); |
| 200 } |
| 201 |
| 194 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override { | 202 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override { |
| 195 UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED( | 203 UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED( |
| 196 "Scheduling.Renderer.MainAndImplFrameTimeDelta", delta); | 204 "Scheduling.Renderer.MainAndImplFrameTimeDelta", delta); |
| 197 } | 205 } |
| 198 }; | 206 }; |
| 199 | 207 |
| 200 class BrowserUMAReporter : public CompositorTimingHistory::UMAReporter { | 208 class BrowserUMAReporter : public CompositorTimingHistory::UMAReporter { |
| 201 public: | 209 public: |
| 202 ~BrowserUMAReporter() override {} | 210 ~BrowserUMAReporter() override {} |
| 203 | 211 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 void AddDrawDuration(base::TimeDelta duration) override { | 265 void AddDrawDuration(base::TimeDelta duration) override { |
| 258 UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Browser.DrawDuration", | 266 UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Browser.DrawDuration", |
| 259 duration); | 267 duration); |
| 260 } | 268 } |
| 261 | 269 |
| 262 void AddSwapToAckLatency(base::TimeDelta duration) override { | 270 void AddSwapToAckLatency(base::TimeDelta duration) override { |
| 263 UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Browser.SwapToAckLatency", | 271 UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Browser.SwapToAckLatency", |
| 264 duration); | 272 duration); |
| 265 } | 273 } |
| 266 | 274 |
| 275 void AddSwapAckWasFast(bool was_fast) override { |
| 276 UMA_HISTOGRAM_BOOLEAN("Scheduling.Browser.SwapAckWasFast", was_fast); |
| 277 } |
| 278 |
| 267 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override { | 279 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override { |
| 268 UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED( | 280 UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED( |
| 269 "Scheduling.Browser.MainAndImplFrameTimeDelta", delta); | 281 "Scheduling.Browser.MainAndImplFrameTimeDelta", delta); |
| 270 } | 282 } |
| 271 }; | 283 }; |
| 272 | 284 |
| 273 class NullUMAReporter : public CompositorTimingHistory::UMAReporter { | 285 class NullUMAReporter : public CompositorTimingHistory::UMAReporter { |
| 274 public: | 286 public: |
| 275 ~NullUMAReporter() override {} | 287 ~NullUMAReporter() override {} |
| 276 void AddBeginMainFrameIntervalCritical(base::TimeDelta interval) override {} | 288 void AddBeginMainFrameIntervalCritical(base::TimeDelta interval) override {} |
| 277 void AddBeginMainFrameIntervalNotCritical(base::TimeDelta interval) override { | 289 void AddBeginMainFrameIntervalNotCritical(base::TimeDelta interval) override { |
| 278 } | 290 } |
| 279 void AddCommitInterval(base::TimeDelta interval) override {} | 291 void AddCommitInterval(base::TimeDelta interval) override {} |
| 280 void AddDrawInterval(base::TimeDelta interval) override {} | 292 void AddDrawInterval(base::TimeDelta interval) override {} |
| 281 void AddBeginMainFrameQueueDurationCriticalDuration( | 293 void AddBeginMainFrameQueueDurationCriticalDuration( |
| 282 base::TimeDelta duration) override {} | 294 base::TimeDelta duration) override {} |
| 283 void AddBeginMainFrameQueueDurationNotCriticalDuration( | 295 void AddBeginMainFrameQueueDurationNotCriticalDuration( |
| 284 base::TimeDelta duration) override {} | 296 base::TimeDelta duration) override {} |
| 285 void AddBeginMainFrameStartToCommitDuration( | 297 void AddBeginMainFrameStartToCommitDuration( |
| 286 base::TimeDelta duration) override {} | 298 base::TimeDelta duration) override {} |
| 287 void AddCommitToReadyToActivateDuration(base::TimeDelta duration) override {} | 299 void AddCommitToReadyToActivateDuration(base::TimeDelta duration) override {} |
| 288 void AddPrepareTilesDuration(base::TimeDelta duration) override {} | 300 void AddPrepareTilesDuration(base::TimeDelta duration) override {} |
| 289 void AddActivateDuration(base::TimeDelta duration) override {} | 301 void AddActivateDuration(base::TimeDelta duration) override {} |
| 290 void AddDrawDuration(base::TimeDelta duration) override {} | 302 void AddDrawDuration(base::TimeDelta duration) override {} |
| 291 void AddSwapToAckLatency(base::TimeDelta duration) override {} | 303 void AddSwapToAckLatency(base::TimeDelta duration) override {} |
| 304 void AddSwapAckWasFast(bool was_fast) override {} |
| 292 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override {} | 305 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override {} |
| 293 }; | 306 }; |
| 294 | 307 |
| 295 } // namespace | 308 } // namespace |
| 296 | 309 |
| 297 CompositorTimingHistory::CompositorTimingHistory( | 310 CompositorTimingHistory::CompositorTimingHistory( |
| 298 bool using_synchronous_renderer_compositor, | 311 bool using_synchronous_renderer_compositor, |
| 299 UMACategory uma_category, | 312 UMACategory uma_category, |
| 300 RenderingStatsInstrumentation* rendering_stats_instrumentation) | 313 RenderingStatsInstrumentation* rendering_stats_instrumentation) |
| 301 : using_synchronous_renderer_compositor_( | 314 : using_synchronous_renderer_compositor_( |
| 302 using_synchronous_renderer_compositor), | 315 using_synchronous_renderer_compositor), |
| 303 enabled_(false), | 316 enabled_(false), |
| 304 did_send_begin_main_frame_(false), | 317 did_send_begin_main_frame_(false), |
| 305 begin_main_frame_needed_continuously_(false), | 318 begin_main_frame_needed_continuously_(false), |
| 306 begin_main_frame_committing_continuously_(false), | 319 begin_main_frame_committing_continuously_(false), |
| 307 compositor_drawing_continuously_(false), | 320 compositor_drawing_continuously_(false), |
| 308 begin_main_frame_queue_duration_history_(kDurationHistorySize), | 321 begin_main_frame_queue_duration_history_(kDurationHistorySize), |
| 309 begin_main_frame_queue_duration_critical_history_(kDurationHistorySize), | 322 begin_main_frame_queue_duration_critical_history_(kDurationHistorySize), |
| 310 begin_main_frame_queue_duration_not_critical_history_( | 323 begin_main_frame_queue_duration_not_critical_history_( |
| 311 kDurationHistorySize), | 324 kDurationHistorySize), |
| 312 begin_main_frame_start_to_commit_duration_history_(kDurationHistorySize), | 325 begin_main_frame_start_to_commit_duration_history_(kDurationHistorySize), |
| 313 commit_to_ready_to_activate_duration_history_(kDurationHistorySize), | 326 commit_to_ready_to_activate_duration_history_(kDurationHistorySize), |
| 314 prepare_tiles_duration_history_(kDurationHistorySize), | 327 prepare_tiles_duration_history_(kDurationHistorySize), |
| 315 activate_duration_history_(kDurationHistorySize), | 328 activate_duration_history_(kDurationHistorySize), |
| 316 draw_duration_history_(kDurationHistorySize), | 329 draw_duration_history_(kDurationHistorySize), |
| 317 begin_main_frame_on_critical_path_(false), | 330 begin_main_frame_on_critical_path_(false), |
| 331 swap_ack_watchdog_enabled_(false), |
| 318 uma_reporter_(CreateUMAReporter(uma_category)), | 332 uma_reporter_(CreateUMAReporter(uma_category)), |
| 319 rendering_stats_instrumentation_(rendering_stats_instrumentation) {} | 333 rendering_stats_instrumentation_(rendering_stats_instrumentation) {} |
| 320 | 334 |
| 321 CompositorTimingHistory::~CompositorTimingHistory() { | 335 CompositorTimingHistory::~CompositorTimingHistory() { |
| 322 } | 336 } |
| 323 | 337 |
| 324 std::unique_ptr<CompositorTimingHistory::UMAReporter> | 338 std::unique_ptr<CompositorTimingHistory::UMAReporter> |
| 325 CompositorTimingHistory::CreateUMAReporter(UMACategory category) { | 339 CompositorTimingHistory::CreateUMAReporter(UMACategory category) { |
| 326 switch (category) { | 340 switch (category) { |
| 327 case RENDERER_UMA: | 341 case RENDERER_UMA: |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 } | 450 } |
| 437 | 451 |
| 438 base::TimeDelta CompositorTimingHistory::DrawDurationEstimate() const { | 452 base::TimeDelta CompositorTimingHistory::DrawDurationEstimate() const { |
| 439 return draw_duration_history_.Percentile(kDrawEstimationPercentile); | 453 return draw_duration_history_.Percentile(kDrawEstimationPercentile); |
| 440 } | 454 } |
| 441 | 455 |
| 442 void CompositorTimingHistory::DidCreateAndInitializeCompositorFrameSink() { | 456 void CompositorTimingHistory::DidCreateAndInitializeCompositorFrameSink() { |
| 443 // After we get a new output surface, we won't get a spurious | 457 // After we get a new output surface, we won't get a spurious |
| 444 // swap ack from the old output surface. | 458 // swap ack from the old output surface. |
| 445 swap_start_time_ = base::TimeTicks(); | 459 swap_start_time_ = base::TimeTicks(); |
| 460 swap_ack_watchdog_enabled_ = false; |
| 446 } | 461 } |
| 447 | 462 |
| 448 void CompositorTimingHistory::WillBeginImplFrame( | 463 void CompositorTimingHistory::WillBeginImplFrame( |
| 449 bool new_active_tree_is_likely) { | 464 bool new_active_tree_is_likely) { |
| 450 // The check for whether a BeginMainFrame was sent anytime between two | 465 // The check for whether a BeginMainFrame was sent anytime between two |
| 451 // BeginImplFrames protects us from not detecting a fast main thread that | 466 // BeginImplFrames protects us from not detecting a fast main thread that |
| 452 // does all it's work and goes idle in between BeginImplFrames. | 467 // does all it's work and goes idle in between BeginImplFrames. |
| 453 // For example, this may happen if an animation is being driven with | 468 // For example, this may happen if an animation is being driven with |
| 454 // setInterval(17) or if input events just happen to arrive in the | 469 // setInterval(17) or if input events just happen to arrive in the |
| 455 // middle of every frame. | 470 // middle of every frame. |
| 456 if (!new_active_tree_is_likely && !did_send_begin_main_frame_) { | 471 if (!new_active_tree_is_likely && !did_send_begin_main_frame_) { |
| 457 SetBeginMainFrameNeededContinuously(false); | 472 SetBeginMainFrameNeededContinuously(false); |
| 458 SetBeginMainFrameCommittingContinuously(false); | 473 SetBeginMainFrameCommittingContinuously(false); |
| 459 } | 474 } |
| 460 | 475 |
| 476 if (swap_ack_watchdog_enabled_) { |
| 477 base::TimeDelta swap_not_acked_time_ = Now() - swap_start_time_; |
| 478 if (swap_not_acked_time_ >= kSwapAckWatchdogTimeout) { |
| 479 uma_reporter_->AddSwapAckWasFast(false); |
| 480 // Only record this UMA once per swap. |
| 481 swap_ack_watchdog_enabled_ = false; |
| 482 } |
| 483 } |
| 484 |
| 461 did_send_begin_main_frame_ = false; | 485 did_send_begin_main_frame_ = false; |
| 462 } | 486 } |
| 463 | 487 |
| 464 void CompositorTimingHistory::WillFinishImplFrame(bool needs_redraw) { | 488 void CompositorTimingHistory::WillFinishImplFrame(bool needs_redraw) { |
| 465 if (!needs_redraw) | 489 if (!needs_redraw) |
| 466 SetCompositorDrawingContinuously(false); | 490 SetCompositorDrawingContinuously(false); |
| 467 } | 491 } |
| 468 | 492 |
| 469 void CompositorTimingHistory::BeginImplFrameNotExpectedSoon() { | 493 void CompositorTimingHistory::BeginImplFrameNotExpectedSoon() { |
| 470 SetBeginMainFrameNeededContinuously(false); | 494 SetBeginMainFrameNeededContinuously(false); |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 690 new_active_tree_draw_end_time_prev_ = draw_end_time; | 714 new_active_tree_draw_end_time_prev_ = draw_end_time; |
| 691 } | 715 } |
| 692 } | 716 } |
| 693 | 717 |
| 694 draw_start_time_ = base::TimeTicks(); | 718 draw_start_time_ = base::TimeTicks(); |
| 695 } | 719 } |
| 696 | 720 |
| 697 void CompositorTimingHistory::DidSwapBuffers() { | 721 void CompositorTimingHistory::DidSwapBuffers() { |
| 698 DCHECK_EQ(base::TimeTicks(), swap_start_time_); | 722 DCHECK_EQ(base::TimeTicks(), swap_start_time_); |
| 699 swap_start_time_ = Now(); | 723 swap_start_time_ = Now(); |
| 724 swap_ack_watchdog_enabled_ = true; |
| 700 } | 725 } |
| 701 | 726 |
| 702 void CompositorTimingHistory::DidSwapBuffersComplete() { | 727 void CompositorTimingHistory::DidSwapBuffersComplete() { |
| 703 DCHECK_NE(base::TimeTicks(), swap_start_time_); | 728 DCHECK_NE(base::TimeTicks(), swap_start_time_); |
| 704 base::TimeDelta swap_to_ack_duration = Now() - swap_start_time_; | 729 base::TimeDelta swap_to_ack_duration = Now() - swap_start_time_; |
| 705 uma_reporter_->AddSwapToAckLatency(swap_to_ack_duration); | 730 uma_reporter_->AddSwapToAckLatency(swap_to_ack_duration); |
| 731 if (swap_ack_watchdog_enabled_) { |
| 732 bool was_fast = swap_to_ack_duration < kSwapAckWatchdogTimeout; |
| 733 uma_reporter_->AddSwapAckWasFast(was_fast); |
| 734 swap_ack_watchdog_enabled_ = false; |
| 735 } |
| 706 swap_start_time_ = base::TimeTicks(); | 736 swap_start_time_ = base::TimeTicks(); |
| 707 } | 737 } |
| 708 | 738 |
| 709 } // namespace cc | 739 } // namespace cc |
| OLD | NEW |