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

Side by Side Diff: cc/scheduler/compositor_timing_history.cc

Issue 2156933003: cc: Add SwapAck watchdog. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Change to 8 seconds Created 4 years, 4 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
« no previous file with comments | « cc/scheduler/compositor_timing_history.h ('k') | cc/scheduler/scheduler_settings.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "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
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
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
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
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
OLDNEW
« no previous file with comments | « cc/scheduler/compositor_timing_history.h ('k') | cc/scheduler/scheduler_settings.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698