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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 const size_t kDurationHistorySize = 60; | 51 const size_t kDurationHistorySize = 60; |
52 const double kBeginMainFrameQueueDurationEstimationPercentile = 90.0; | 52 const double kBeginMainFrameQueueDurationEstimationPercentile = 90.0; |
53 const double kBeginMainFrameQueueDurationCriticalEstimationPercentile = 90.0; | 53 const double kBeginMainFrameQueueDurationCriticalEstimationPercentile = 90.0; |
54 const double kBeginMainFrameQueueDurationNotCriticalEstimationPercentile = 90.0; | 54 const double kBeginMainFrameQueueDurationNotCriticalEstimationPercentile = 90.0; |
55 const double kBeginMainFrameStartToCommitEstimationPercentile = 90.0; | 55 const double kBeginMainFrameStartToCommitEstimationPercentile = 90.0; |
56 const double kCommitToReadyToActivateEstimationPercentile = 90.0; | 56 const double kCommitToReadyToActivateEstimationPercentile = 90.0; |
57 const double kPrepareTilesEstimationPercentile = 90.0; | 57 const double kPrepareTilesEstimationPercentile = 90.0; |
58 const double kActivateEstimationPercentile = 90.0; | 58 const double kActivateEstimationPercentile = 90.0; |
59 const double kDrawEstimationPercentile = 90.0; | 59 const double kDrawEstimationPercentile = 90.0; |
60 | 60 |
| 61 // The watchdog uses a combination of BeginImplFrame counts and |
| 62 // actual timestamps to avoid calling Now() too often or adding |
| 63 // unnecessary idle wakeups. |
| 64 // This will break if we aren't receiving BeginFrames, but this |
| 65 // is primarily for crbug.com/602486, where we are receiving them. |
| 66 const int kSwapAckWatchdogBeginImplFrameCount = 8 * 61; |
| 67 const int kSwapAckWatchdogBeginImplFrameReCount = 60; |
| 68 const base::TimeDelta kSwapAckWatchdogTimeout = |
| 69 base::TimeDelta::FromMicroseconds(8000000); |
| 70 |
61 const int kUmaDurationMinMicros = 1; | 71 const int kUmaDurationMinMicros = 1; |
62 const int64_t kUmaDurationMaxMicros = base::Time::kMicrosecondsPerSecond / 5; | 72 const int64_t kUmaDurationMaxMicros = base::Time::kMicrosecondsPerSecond / 5; |
63 const int kUmaDurationBucketCount = 100; | 73 const int kUmaDurationBucketCount = 100; |
64 | 74 |
65 // This macro is deprecated since its bucket count uses too much bandwidth. | 75 // This macro is deprecated since its bucket count uses too much bandwidth. |
66 // It also has sub-optimal range and bucket distribution. | 76 // It also has sub-optimal range and bucket distribution. |
67 // TODO(brianderson): Delete this macro and associated UMAs once there is | 77 // TODO(brianderson): Delete this macro and associated UMAs once there is |
68 // sufficient overlap with the re-bucketed UMAs. | 78 // sufficient overlap with the re-bucketed UMAs. |
69 #define UMA_HISTOGRAM_CUSTOM_TIMES_MICROS(name, sample) \ | 79 #define UMA_HISTOGRAM_CUSTOM_TIMES_MICROS(name, sample) \ |
70 UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample.InMicroseconds(), \ | 80 UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample.InMicroseconds(), \ |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 void AddActivateDuration(base::TimeDelta duration) override {} | 299 void AddActivateDuration(base::TimeDelta duration) override {} |
290 void AddDrawDuration(base::TimeDelta duration) override {} | 300 void AddDrawDuration(base::TimeDelta duration) override {} |
291 void AddSwapToAckLatency(base::TimeDelta duration) override {} | 301 void AddSwapToAckLatency(base::TimeDelta duration) override {} |
292 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override {} | 302 void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override {} |
293 }; | 303 }; |
294 | 304 |
295 } // namespace | 305 } // namespace |
296 | 306 |
297 CompositorTimingHistory::CompositorTimingHistory( | 307 CompositorTimingHistory::CompositorTimingHistory( |
298 bool using_synchronous_renderer_compositor, | 308 bool using_synchronous_renderer_compositor, |
| 309 bool enable_swap_ack_watchdog, |
299 UMACategory uma_category, | 310 UMACategory uma_category, |
300 RenderingStatsInstrumentation* rendering_stats_instrumentation) | 311 RenderingStatsInstrumentation* rendering_stats_instrumentation) |
301 : using_synchronous_renderer_compositor_( | 312 : using_synchronous_renderer_compositor_( |
302 using_synchronous_renderer_compositor), | 313 using_synchronous_renderer_compositor), |
303 enabled_(false), | 314 enabled_(false), |
304 did_send_begin_main_frame_(false), | 315 did_send_begin_main_frame_(false), |
305 begin_main_frame_needed_continuously_(false), | 316 begin_main_frame_needed_continuously_(false), |
306 begin_main_frame_committing_continuously_(false), | 317 begin_main_frame_committing_continuously_(false), |
307 compositor_drawing_continuously_(false), | 318 compositor_drawing_continuously_(false), |
308 begin_main_frame_queue_duration_history_(kDurationHistorySize), | 319 begin_main_frame_queue_duration_history_(kDurationHistorySize), |
309 begin_main_frame_queue_duration_critical_history_(kDurationHistorySize), | 320 begin_main_frame_queue_duration_critical_history_(kDurationHistorySize), |
310 begin_main_frame_queue_duration_not_critical_history_( | 321 begin_main_frame_queue_duration_not_critical_history_( |
311 kDurationHistorySize), | 322 kDurationHistorySize), |
312 begin_main_frame_start_to_commit_duration_history_(kDurationHistorySize), | 323 begin_main_frame_start_to_commit_duration_history_(kDurationHistorySize), |
313 commit_to_ready_to_activate_duration_history_(kDurationHistorySize), | 324 commit_to_ready_to_activate_duration_history_(kDurationHistorySize), |
314 prepare_tiles_duration_history_(kDurationHistorySize), | 325 prepare_tiles_duration_history_(kDurationHistorySize), |
315 activate_duration_history_(kDurationHistorySize), | 326 activate_duration_history_(kDurationHistorySize), |
316 draw_duration_history_(kDurationHistorySize), | 327 draw_duration_history_(kDurationHistorySize), |
317 begin_main_frame_on_critical_path_(false), | 328 begin_main_frame_on_critical_path_(false), |
| 329 swap_ack_watchdog_enabled_(enable_swap_ack_watchdog), |
| 330 swap_ack_watchdog_begin_impl_frame_count_(0), |
318 uma_reporter_(CreateUMAReporter(uma_category)), | 331 uma_reporter_(CreateUMAReporter(uma_category)), |
319 rendering_stats_instrumentation_(rendering_stats_instrumentation) {} | 332 rendering_stats_instrumentation_(rendering_stats_instrumentation) {} |
320 | 333 |
321 CompositorTimingHistory::~CompositorTimingHistory() { | 334 CompositorTimingHistory::~CompositorTimingHistory() { |
322 } | 335 } |
323 | 336 |
324 std::unique_ptr<CompositorTimingHistory::UMAReporter> | 337 std::unique_ptr<CompositorTimingHistory::UMAReporter> |
325 CompositorTimingHistory::CreateUMAReporter(UMACategory category) { | 338 CompositorTimingHistory::CreateUMAReporter(UMACategory category) { |
326 switch (category) { | 339 switch (category) { |
327 case RENDERER_UMA: | 340 case RENDERER_UMA: |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 } | 449 } |
437 | 450 |
438 base::TimeDelta CompositorTimingHistory::DrawDurationEstimate() const { | 451 base::TimeDelta CompositorTimingHistory::DrawDurationEstimate() const { |
439 return draw_duration_history_.Percentile(kDrawEstimationPercentile); | 452 return draw_duration_history_.Percentile(kDrawEstimationPercentile); |
440 } | 453 } |
441 | 454 |
442 void CompositorTimingHistory::DidCreateAndInitializeOutputSurface() { | 455 void CompositorTimingHistory::DidCreateAndInitializeOutputSurface() { |
443 // After we get a new output surface, we won't get a spurious | 456 // After we get a new output surface, we won't get a spurious |
444 // swap ack from the old output surface. | 457 // swap ack from the old output surface. |
445 swap_start_time_ = base::TimeTicks(); | 458 swap_start_time_ = base::TimeTicks(); |
| 459 swap_ack_watchdog_begin_impl_frame_count_ = 0; |
446 } | 460 } |
447 | 461 |
448 void CompositorTimingHistory::WillBeginImplFrame( | 462 void CompositorTimingHistory::WillBeginImplFrame( |
449 bool new_active_tree_is_likely) { | 463 bool new_active_tree_is_likely) { |
450 // The check for whether a BeginMainFrame was sent anytime between two | 464 // The check for whether a BeginMainFrame was sent anytime between two |
451 // BeginImplFrames protects us from not detecting a fast main thread that | 465 // BeginImplFrames protects us from not detecting a fast main thread that |
452 // does all it's work and goes idle in between BeginImplFrames. | 466 // does all it's work and goes idle in between BeginImplFrames. |
453 // For example, this may happen if an animation is being driven with | 467 // 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 | 468 // setInterval(17) or if input events just happen to arrive in the |
455 // middle of every frame. | 469 // middle of every frame. |
456 if (!new_active_tree_is_likely && !did_send_begin_main_frame_) { | 470 if (!new_active_tree_is_likely && !did_send_begin_main_frame_) { |
457 SetBeginMainFrameNeededContinuously(false); | 471 SetBeginMainFrameNeededContinuously(false); |
458 SetBeginMainFrameCommittingContinuously(false); | 472 SetBeginMainFrameCommittingContinuously(false); |
459 } | 473 } |
460 | 474 |
| 475 // After N BeginImplFrames, check if the swap ack is taking too long. |
| 476 // If it is, crash to get diagnostic information. |
| 477 // Otherwise, check again in M BeginImplFrames. |
| 478 if (swap_ack_watchdog_enabled_ && !swap_start_time_.is_null()) { |
| 479 swap_ack_watchdog_begin_impl_frame_count_++; |
| 480 if (swap_ack_watchdog_begin_impl_frame_count_ == |
| 481 kSwapAckWatchdogBeginImplFrameCount) { |
| 482 base::TimeDelta swap_not_acked_time_ = Now() - swap_start_time_; |
| 483 CHECK_LT(swap_not_acked_time_, kSwapAckWatchdogTimeout); |
| 484 swap_ack_watchdog_begin_impl_frame_count_ -= |
| 485 kSwapAckWatchdogBeginImplFrameReCount; |
| 486 } |
| 487 } |
| 488 |
461 did_send_begin_main_frame_ = false; | 489 did_send_begin_main_frame_ = false; |
462 } | 490 } |
463 | 491 |
464 void CompositorTimingHistory::WillFinishImplFrame(bool needs_redraw) { | 492 void CompositorTimingHistory::WillFinishImplFrame(bool needs_redraw) { |
465 if (!needs_redraw) | 493 if (!needs_redraw) |
466 SetCompositorDrawingContinuously(false); | 494 SetCompositorDrawingContinuously(false); |
467 } | 495 } |
468 | 496 |
469 void CompositorTimingHistory::BeginImplFrameNotExpectedSoon() { | 497 void CompositorTimingHistory::BeginImplFrameNotExpectedSoon() { |
470 SetBeginMainFrameNeededContinuously(false); | 498 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; | 718 new_active_tree_draw_end_time_prev_ = draw_end_time; |
691 } | 719 } |
692 } | 720 } |
693 | 721 |
694 draw_start_time_ = base::TimeTicks(); | 722 draw_start_time_ = base::TimeTicks(); |
695 } | 723 } |
696 | 724 |
697 void CompositorTimingHistory::DidSwapBuffers() { | 725 void CompositorTimingHistory::DidSwapBuffers() { |
698 DCHECK_EQ(base::TimeTicks(), swap_start_time_); | 726 DCHECK_EQ(base::TimeTicks(), swap_start_time_); |
699 swap_start_time_ = Now(); | 727 swap_start_time_ = Now(); |
| 728 swap_ack_watchdog_begin_impl_frame_count_ = 0; |
700 } | 729 } |
701 | 730 |
702 void CompositorTimingHistory::DidSwapBuffersComplete() { | 731 void CompositorTimingHistory::DidSwapBuffersComplete() { |
703 DCHECK_NE(base::TimeTicks(), swap_start_time_); | 732 DCHECK_NE(base::TimeTicks(), swap_start_time_); |
704 base::TimeDelta swap_to_ack_duration = Now() - swap_start_time_; | 733 base::TimeDelta swap_to_ack_duration = Now() - swap_start_time_; |
705 uma_reporter_->AddSwapToAckLatency(swap_to_ack_duration); | 734 uma_reporter_->AddSwapToAckLatency(swap_to_ack_duration); |
706 swap_start_time_ = base::TimeTicks(); | 735 swap_start_time_ = base::TimeTicks(); |
707 } | 736 } |
708 | 737 |
709 } // namespace cc | 738 } // namespace cc |
OLD | NEW |