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