| Index: cc/scheduler/compositor_timing_history.cc
|
| diff --git a/cc/scheduler/compositor_timing_history.cc b/cc/scheduler/compositor_timing_history.cc
|
| index 8b474c09b3d20a070095c45f3c6cb3caf722bedd..c4267b0a5426a2f01bac1abf735104e5d5fd30a9 100644
|
| --- a/cc/scheduler/compositor_timing_history.cc
|
| +++ b/cc/scheduler/compositor_timing_history.cc
|
| @@ -58,6 +58,16 @@ const double kPrepareTilesEstimationPercentile = 90.0;
|
| const double kActivateEstimationPercentile = 90.0;
|
| const double kDrawEstimationPercentile = 90.0;
|
|
|
| +// The watchdog uses a combination of BeginImplFrame counts and
|
| +// actual timestamps to avoid calling Now() too often or adding
|
| +// unnecessary idle wakeups.
|
| +// This will break if we aren't receiving BeginFrames, but this
|
| +// is primarily for crbug.com/602486, where we are receiving them.
|
| +const int kSwapAckWatchdogBeginImplFrameCount = 8 * 61;
|
| +const int kSwapAckWatchdogBeginImplFrameReCount = 60;
|
| +const base::TimeDelta kSwapAckWatchdogTimeout =
|
| + base::TimeDelta::FromMicroseconds(8000000);
|
| +
|
| const int kUmaDurationMinMicros = 1;
|
| const int64_t kUmaDurationMaxMicros = base::Time::kMicrosecondsPerSecond / 5;
|
| const int kUmaDurationBucketCount = 100;
|
| @@ -296,6 +306,7 @@ class NullUMAReporter : public CompositorTimingHistory::UMAReporter {
|
|
|
| CompositorTimingHistory::CompositorTimingHistory(
|
| bool using_synchronous_renderer_compositor,
|
| + bool enable_swap_ack_watchdog,
|
| UMACategory uma_category,
|
| RenderingStatsInstrumentation* rendering_stats_instrumentation)
|
| : using_synchronous_renderer_compositor_(
|
| @@ -315,6 +326,8 @@ CompositorTimingHistory::CompositorTimingHistory(
|
| activate_duration_history_(kDurationHistorySize),
|
| draw_duration_history_(kDurationHistorySize),
|
| begin_main_frame_on_critical_path_(false),
|
| + swap_ack_watchdog_enabled_(enable_swap_ack_watchdog),
|
| + swap_ack_watchdog_begin_impl_frame_count_(0),
|
| uma_reporter_(CreateUMAReporter(uma_category)),
|
| rendering_stats_instrumentation_(rendering_stats_instrumentation) {}
|
|
|
| @@ -443,6 +456,7 @@ void CompositorTimingHistory::DidCreateAndInitializeOutputSurface() {
|
| // After we get a new output surface, we won't get a spurious
|
| // swap ack from the old output surface.
|
| swap_start_time_ = base::TimeTicks();
|
| + swap_ack_watchdog_begin_impl_frame_count_ = 0;
|
| }
|
|
|
| void CompositorTimingHistory::WillBeginImplFrame(
|
| @@ -458,6 +472,20 @@ void CompositorTimingHistory::WillBeginImplFrame(
|
| SetBeginMainFrameCommittingContinuously(false);
|
| }
|
|
|
| + // After N BeginImplFrames, check if the swap ack is taking too long.
|
| + // If it is, crash to get diagnostic information.
|
| + // Otherwise, check again in M BeginImplFrames.
|
| + if (swap_ack_watchdog_enabled_ && !swap_start_time_.is_null()) {
|
| + swap_ack_watchdog_begin_impl_frame_count_++;
|
| + if (swap_ack_watchdog_begin_impl_frame_count_ ==
|
| + kSwapAckWatchdogBeginImplFrameCount) {
|
| + base::TimeDelta swap_not_acked_time_ = Now() - swap_start_time_;
|
| + CHECK_LT(swap_not_acked_time_, kSwapAckWatchdogTimeout);
|
| + swap_ack_watchdog_begin_impl_frame_count_ -=
|
| + kSwapAckWatchdogBeginImplFrameReCount;
|
| + }
|
| + }
|
| +
|
| did_send_begin_main_frame_ = false;
|
| }
|
|
|
| @@ -697,6 +725,7 @@ void CompositorTimingHistory::DidDraw(bool used_new_active_tree,
|
| void CompositorTimingHistory::DidSwapBuffers() {
|
| DCHECK_EQ(base::TimeTicks(), swap_start_time_);
|
| swap_start_time_ = Now();
|
| + swap_ack_watchdog_begin_impl_frame_count_ = 0;
|
| }
|
|
|
| void CompositorTimingHistory::DidSwapBuffersComplete() {
|
|
|