| 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 "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
| 8 #include "base/trace_event/trace_event.h" | 8 #include "base/trace_event/trace_event.h" |
| 9 #include "cc/debug/rendering_stats_instrumentation.h" | 9 #include "cc/debug/rendering_stats_instrumentation.h" |
| 10 | 10 |
| 11 // The estimates that affect the compositors deadline use the 100th percentile |
| 12 // to avoid missing the Browser's deadline. |
| 13 // The estimates related to main-thread responsiveness affect whether |
| 14 // we attempt to recovery latency or not and use the 50th percentile. |
| 15 // TODO(brianderson): Fine tune the percentiles below. |
| 11 const size_t kDurationHistorySize = 60; | 16 const size_t kDurationHistorySize = 60; |
| 12 const double kCommitAndActivationDurationEstimationPercentile = 50.0; | 17 const double kBeginMainFrameToCommitEstimationPercentile = 50.0; |
| 13 const double kDrawDurationEstimationPercentile = 100.0; | 18 const double kCommitToReadyToActivateEstimationPercentile = 50.0; |
| 14 const int kDrawDurationEstimatePaddingInMicroseconds = 0; | 19 const double kPrepareTilesEstimationPercentile = 100.0; |
| 20 const double kActivateEstimationPercentile = 100.0; |
| 21 const double kDrawEstimationPercentile = 100.0; |
| 15 | 22 |
| 16 namespace cc { | 23 namespace cc { |
| 17 | 24 |
| 18 CompositorTimingHistory::CompositorTimingHistory( | 25 CompositorTimingHistory::CompositorTimingHistory( |
| 19 RenderingStatsInstrumentation* rendering_stats_instrumentation) | 26 RenderingStatsInstrumentation* rendering_stats_instrumentation) |
| 20 : draw_duration_history_(kDurationHistorySize), | 27 : enabled_(false), |
| 21 begin_main_frame_to_commit_duration_history_(kDurationHistorySize), | 28 begin_main_frame_to_commit_duration_history_(kDurationHistorySize), |
| 22 commit_to_activate_duration_history_(kDurationHistorySize), | 29 commit_to_ready_to_activate_duration_history_(kDurationHistorySize), |
| 30 prepare_tiles_duration_history_(kDurationHistorySize), |
| 31 activate_duration_history_(kDurationHistorySize), |
| 32 draw_duration_history_(kDurationHistorySize), |
| 23 rendering_stats_instrumentation_(rendering_stats_instrumentation) { | 33 rendering_stats_instrumentation_(rendering_stats_instrumentation) { |
| 24 } | 34 } |
| 25 | 35 |
| 26 CompositorTimingHistory::~CompositorTimingHistory() { | 36 CompositorTimingHistory::~CompositorTimingHistory() { |
| 27 } | 37 } |
| 28 | 38 |
| 29 void CompositorTimingHistory::AsValueInto( | 39 void CompositorTimingHistory::AsValueInto( |
| 30 base::trace_event::TracedValue* state) const { | 40 base::trace_event::TracedValue* state) const { |
| 31 state->SetDouble("begin_main_frame_to_commit_duration_estimate_ms", | 41 state->SetDouble("begin_main_frame_to_commit_duration_estimate_ms", |
| 32 BeginMainFrameToCommitDurationEstimate().InMillisecondsF()); | 42 BeginMainFrameToCommitDurationEstimate().InMillisecondsF()); |
| 33 state->SetDouble("commit_to_activate_duration_estimate_ms", | 43 state->SetDouble("commit_to_ready_to_activate_duration_estimate_ms", |
| 34 CommitToActivateDurationEstimate().InMillisecondsF()); | 44 CommitToReadyToActivateDurationEstimate().InMillisecondsF()); |
| 45 state->SetDouble("prepare_tiles_duration_estimate_ms", |
| 46 PrepareTilesDurationEstimate().InMillisecondsF()); |
| 47 state->SetDouble("activate_duration_estimate_ms", |
| 48 ActivateDurationEstimate().InMillisecondsF()); |
| 35 state->SetDouble("draw_duration_estimate_ms", | 49 state->SetDouble("draw_duration_estimate_ms", |
| 36 DrawDurationEstimate().InMillisecondsF()); | 50 DrawDurationEstimate().InMillisecondsF()); |
| 37 } | 51 } |
| 38 | 52 |
| 39 base::TimeDelta CompositorTimingHistory::DrawDurationEstimate() const { | 53 base::TimeTicks CompositorTimingHistory::Now() const { |
| 40 base::TimeDelta historical_estimate = | 54 return base::TimeTicks::Now(); |
| 41 draw_duration_history_.Percentile(kDrawDurationEstimationPercentile); | 55 } |
| 42 base::TimeDelta padding = base::TimeDelta::FromMicroseconds( | 56 |
| 43 kDrawDurationEstimatePaddingInMicroseconds); | 57 void CompositorTimingHistory::SetRecordingEnabled(bool enabled) { |
| 44 return historical_estimate + padding; | 58 enabled_ = enabled; |
| 45 } | 59 } |
| 46 | 60 |
| 47 base::TimeDelta | 61 base::TimeDelta |
| 48 CompositorTimingHistory::BeginMainFrameToCommitDurationEstimate() const { | 62 CompositorTimingHistory::BeginMainFrameToCommitDurationEstimate() const { |
| 49 return begin_main_frame_to_commit_duration_history_.Percentile( | 63 return begin_main_frame_to_commit_duration_history_.Percentile( |
| 50 kCommitAndActivationDurationEstimationPercentile); | 64 kBeginMainFrameToCommitEstimationPercentile); |
| 51 } | 65 } |
| 52 | 66 |
| 53 base::TimeDelta CompositorTimingHistory::CommitToActivateDurationEstimate() | 67 base::TimeDelta |
| 54 const { | 68 CompositorTimingHistory::CommitToReadyToActivateDurationEstimate() const { |
| 55 return commit_to_activate_duration_history_.Percentile( | 69 return commit_to_ready_to_activate_duration_history_.Percentile( |
| 56 kCommitAndActivationDurationEstimationPercentile); | 70 kCommitToReadyToActivateEstimationPercentile); |
| 71 } |
| 72 |
| 73 base::TimeDelta CompositorTimingHistory::PrepareTilesDurationEstimate() const { |
| 74 return prepare_tiles_duration_history_.Percentile( |
| 75 kPrepareTilesEstimationPercentile); |
| 76 } |
| 77 |
| 78 base::TimeDelta CompositorTimingHistory::ActivateDurationEstimate() const { |
| 79 return activate_duration_history_.Percentile(kActivateEstimationPercentile); |
| 80 } |
| 81 |
| 82 base::TimeDelta CompositorTimingHistory::DrawDurationEstimate() const { |
| 83 return draw_duration_history_.Percentile(kDrawEstimationPercentile); |
| 57 } | 84 } |
| 58 | 85 |
| 59 void CompositorTimingHistory::WillBeginMainFrame() { | 86 void CompositorTimingHistory::WillBeginMainFrame() { |
| 60 begin_main_frame_sent_time_ = base::TimeTicks::Now(); | 87 DCHECK_EQ(base::TimeTicks(), begin_main_frame_sent_time_); |
| 88 begin_main_frame_sent_time_ = Now(); |
| 89 } |
| 90 |
| 91 void CompositorTimingHistory::BeginMainFrameAborted() { |
| 92 DidCommit(); |
| 61 } | 93 } |
| 62 | 94 |
| 63 void CompositorTimingHistory::DidCommit() { | 95 void CompositorTimingHistory::DidCommit() { |
| 64 commit_complete_time_ = base::TimeTicks::Now(); | 96 DCHECK_NE(base::TimeTicks(), begin_main_frame_sent_time_); |
| 97 |
| 98 commit_time_ = Now(); |
| 99 |
| 65 base::TimeDelta begin_main_frame_to_commit_duration = | 100 base::TimeDelta begin_main_frame_to_commit_duration = |
| 66 commit_complete_time_ - begin_main_frame_sent_time_; | 101 commit_time_ - begin_main_frame_sent_time_; |
| 67 | 102 |
| 68 // Before adding the new data point to the timing history, see what we would | 103 // Before adding the new data point to the timing history, see what we would |
| 69 // have predicted for this frame. This allows us to keep track of the accuracy | 104 // have predicted for this frame. This allows us to keep track of the accuracy |
| 70 // of our predictions. | 105 // of our predictions. |
| 71 rendering_stats_instrumentation_->AddBeginMainFrameToCommitDuration( | 106 rendering_stats_instrumentation_->AddBeginMainFrameToCommitDuration( |
| 72 begin_main_frame_to_commit_duration, | 107 begin_main_frame_to_commit_duration, |
| 73 BeginMainFrameToCommitDurationEstimate()); | 108 BeginMainFrameToCommitDurationEstimate()); |
| 74 | 109 |
| 75 begin_main_frame_to_commit_duration_history_.InsertSample( | 110 if (enabled_) { |
| 76 begin_main_frame_to_commit_duration); | 111 begin_main_frame_to_commit_duration_history_.InsertSample( |
| 112 begin_main_frame_to_commit_duration); |
| 113 } |
| 114 |
| 115 begin_main_frame_sent_time_ = base::TimeTicks(); |
| 77 } | 116 } |
| 78 | 117 |
| 79 void CompositorTimingHistory::DidActivateSyncTree() { | 118 void CompositorTimingHistory::WillPrepareTiles() { |
| 80 base::TimeDelta commit_to_activate_duration = | 119 DCHECK_EQ(base::TimeTicks(), start_prepare_tiles_time_); |
| 81 base::TimeTicks::Now() - commit_complete_time_; | 120 start_prepare_tiles_time_ = Now(); |
| 121 } |
| 122 |
| 123 void CompositorTimingHistory::DidPrepareTiles() { |
| 124 DCHECK_NE(base::TimeTicks(), start_prepare_tiles_time_); |
| 125 |
| 126 if (enabled_) { |
| 127 base::TimeDelta prepare_tiles_duration = Now() - start_prepare_tiles_time_; |
| 128 prepare_tiles_duration_history_.InsertSample(prepare_tiles_duration); |
| 129 } |
| 130 |
| 131 start_prepare_tiles_time_ = base::TimeTicks(); |
| 132 } |
| 133 |
| 134 void CompositorTimingHistory::ReadyToActivate() { |
| 135 // We only care about the first ready to activate signal |
| 136 // after a commit. |
| 137 if (commit_time_ == base::TimeTicks()) |
| 138 return; |
| 139 |
| 140 base::TimeDelta time_since_commit = Now() - commit_time_; |
| 82 | 141 |
| 83 // Before adding the new data point to the timing history, see what we would | 142 // Before adding the new data point to the timing history, see what we would |
| 84 // have predicted for this frame. This allows us to keep track of the accuracy | 143 // have predicted for this frame. This allows us to keep track of the accuracy |
| 85 // of our predictions. | 144 // of our predictions. |
| 86 rendering_stats_instrumentation_->AddCommitToActivateDuration( | 145 rendering_stats_instrumentation_->AddCommitToActivateDuration( |
| 87 commit_to_activate_duration, CommitToActivateDurationEstimate()); | 146 time_since_commit, CommitToReadyToActivateDurationEstimate()); |
| 88 | 147 |
| 89 commit_to_activate_duration_history_.InsertSample( | 148 if (enabled_) { |
| 90 commit_to_activate_duration); | 149 commit_to_ready_to_activate_duration_history_.InsertSample( |
| 150 time_since_commit); |
| 151 } |
| 152 |
| 153 commit_time_ = base::TimeTicks(); |
| 91 } | 154 } |
| 92 | 155 |
| 93 void CompositorTimingHistory::DidStartDrawing() { | 156 void CompositorTimingHistory::WillActivate() { |
| 94 start_draw_time_ = base::TimeTicks::Now(); | 157 DCHECK_EQ(base::TimeTicks(), start_activate_time_); |
| 158 start_activate_time_ = Now(); |
| 95 } | 159 } |
| 96 | 160 |
| 97 void CompositorTimingHistory::DidFinishDrawing() { | 161 void CompositorTimingHistory::DidActivate() { |
| 98 base::TimeDelta draw_duration = base::TimeTicks::Now() - start_draw_time_; | 162 DCHECK_NE(base::TimeTicks(), start_activate_time_); |
| 163 if (enabled_) { |
| 164 base::TimeDelta activate_duration = Now() - start_activate_time_; |
| 165 activate_duration_history_.InsertSample(activate_duration); |
| 166 } |
| 167 start_activate_time_ = base::TimeTicks(); |
| 168 } |
| 169 |
| 170 void CompositorTimingHistory::WillDraw() { |
| 171 DCHECK_EQ(base::TimeTicks(), start_draw_time_); |
| 172 start_draw_time_ = Now(); |
| 173 } |
| 174 |
| 175 void CompositorTimingHistory::DidDraw() { |
| 176 DCHECK_NE(base::TimeTicks(), start_draw_time_); |
| 177 base::TimeDelta draw_duration = Now() - start_draw_time_; |
| 99 | 178 |
| 100 // Before adding the new data point to the timing history, see what we would | 179 // Before adding the new data point to the timing history, see what we would |
| 101 // have predicted for this frame. This allows us to keep track of the accuracy | 180 // have predicted for this frame. This allows us to keep track of the accuracy |
| 102 // of our predictions. | 181 // of our predictions. |
| 103 base::TimeDelta draw_duration_estimate = DrawDurationEstimate(); | 182 base::TimeDelta draw_duration_estimate = DrawDurationEstimate(); |
| 104 rendering_stats_instrumentation_->AddDrawDuration(draw_duration, | 183 rendering_stats_instrumentation_->AddDrawDuration(draw_duration, |
| 105 draw_duration_estimate); | 184 draw_duration_estimate); |
| 106 | 185 |
| 107 AddDrawDurationUMA(draw_duration, draw_duration_estimate); | 186 AddDrawDurationUMA(draw_duration, draw_duration_estimate); |
| 108 | 187 |
| 109 draw_duration_history_.InsertSample(draw_duration); | 188 if (enabled_) { |
| 189 draw_duration_history_.InsertSample(draw_duration); |
| 190 } |
| 191 |
| 192 start_draw_time_ = base::TimeTicks(); |
| 110 } | 193 } |
| 111 | 194 |
| 112 void CompositorTimingHistory::AddDrawDurationUMA( | 195 void CompositorTimingHistory::AddDrawDurationUMA( |
| 113 base::TimeDelta draw_duration, | 196 base::TimeDelta draw_duration, |
| 114 base::TimeDelta draw_duration_estimate) { | 197 base::TimeDelta draw_duration_estimate) { |
| 115 base::TimeDelta draw_duration_overestimate; | 198 base::TimeDelta draw_duration_overestimate; |
| 116 base::TimeDelta draw_duration_underestimate; | 199 base::TimeDelta draw_duration_underestimate; |
| 117 if (draw_duration > draw_duration_estimate) | 200 if (draw_duration > draw_duration_estimate) |
| 118 draw_duration_underestimate = draw_duration - draw_duration_estimate; | 201 draw_duration_underestimate = draw_duration - draw_duration_estimate; |
| 119 else | 202 else |
| 120 draw_duration_overestimate = draw_duration_estimate - draw_duration; | 203 draw_duration_overestimate = draw_duration_estimate - draw_duration; |
| 121 UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDuration", draw_duration, | 204 UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDuration", draw_duration, |
| 122 base::TimeDelta::FromMilliseconds(1), | 205 base::TimeDelta::FromMilliseconds(1), |
| 123 base::TimeDelta::FromMilliseconds(100), 50); | 206 base::TimeDelta::FromMilliseconds(100), 50); |
| 124 UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationUnderestimate", | 207 UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationUnderestimate", |
| 125 draw_duration_underestimate, | 208 draw_duration_underestimate, |
| 126 base::TimeDelta::FromMilliseconds(1), | 209 base::TimeDelta::FromMilliseconds(1), |
| 127 base::TimeDelta::FromMilliseconds(100), 50); | 210 base::TimeDelta::FromMilliseconds(100), 50); |
| 128 UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationOverestimate", | 211 UMA_HISTOGRAM_CUSTOM_TIMES("Renderer.DrawDurationOverestimate", |
| 129 draw_duration_overestimate, | 212 draw_duration_overestimate, |
| 130 base::TimeDelta::FromMilliseconds(1), | 213 base::TimeDelta::FromMilliseconds(1), |
| 131 base::TimeDelta::FromMilliseconds(100), 50); | 214 base::TimeDelta::FromMilliseconds(100), 50); |
| 132 } | 215 } |
| 133 | 216 |
| 134 } // namespace cc | 217 } // namespace cc |
| OLD | NEW |