OLD | NEW |
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 1 // Copyright 2011 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/scheduler_state_machine.h" | 5 #include "cc/scheduler/scheduler_state_machine.h" |
6 | 6 |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/debug/trace_event_argument.h" | |
9 #include "base/format_macros.h" | 8 #include "base/format_macros.h" |
10 #include "base/logging.h" | 9 #include "base/logging.h" |
11 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
12 #include "base/values.h" | 11 #include "base/values.h" |
13 #include "ui/gfx/frame_time.h" | 12 #include "ui/gfx/frame_time.h" |
14 | 13 |
15 namespace cc { | 14 namespace cc { |
16 | 15 |
17 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) | 16 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) |
18 : settings_(settings), | 17 : settings_(settings), |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 return "ACTION_DRAW_AND_SWAP_ABORT"; | 140 return "ACTION_DRAW_AND_SWAP_ABORT"; |
142 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: | 141 case ACTION_BEGIN_OUTPUT_SURFACE_CREATION: |
143 return "ACTION_BEGIN_OUTPUT_SURFACE_CREATION"; | 142 return "ACTION_BEGIN_OUTPUT_SURFACE_CREATION"; |
144 case ACTION_MANAGE_TILES: | 143 case ACTION_MANAGE_TILES: |
145 return "ACTION_MANAGE_TILES"; | 144 return "ACTION_MANAGE_TILES"; |
146 } | 145 } |
147 NOTREACHED(); | 146 NOTREACHED(); |
148 return "???"; | 147 return "???"; |
149 } | 148 } |
150 | 149 |
151 scoped_refptr<base::debug::ConvertableToTraceFormat> | 150 scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const { |
152 SchedulerStateMachine::AsValue() const { | 151 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); |
153 scoped_refptr<base::debug::TracedValue> state = | |
154 new base::debug::TracedValue(); | |
155 AsValueInto(state); | |
156 return state; | |
157 } | |
158 | 152 |
159 void SchedulerStateMachine::AsValueInto(base::debug::TracedValue* state) const { | 153 scoped_ptr<base::DictionaryValue> major_state(new base::DictionaryValue); |
160 state->BeginDictionary("major_state"); | 154 major_state->SetString("next_action", ActionToString(NextAction())); |
161 state->SetString("next_action", ActionToString(NextAction())); | 155 major_state->SetString("begin_impl_frame_state", |
162 state->SetString("begin_impl_frame_state", | 156 BeginImplFrameStateToString(begin_impl_frame_state_)); |
163 BeginImplFrameStateToString(begin_impl_frame_state_)); | 157 major_state->SetString("commit_state", CommitStateToString(commit_state_)); |
164 state->SetString("commit_state", CommitStateToString(commit_state_)); | 158 major_state->SetString("output_surface_state_", |
165 state->SetString("output_surface_state_", | 159 OutputSurfaceStateToString(output_surface_state_)); |
166 OutputSurfaceStateToString(output_surface_state_)); | 160 major_state->SetString( |
167 state->SetString("forced_redraw_state", | 161 "forced_redraw_state", |
168 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_)); | 162 ForcedRedrawOnTimeoutStateToString(forced_redraw_state_)); |
169 state->EndDictionary(); | 163 state->Set("major_state", major_state.release()); |
170 | 164 |
171 state->BeginDictionary("major_timestamps_in_ms"); | 165 scoped_ptr<base::DictionaryValue> timestamps_state(new base::DictionaryValue); |
172 base::TimeTicks now = gfx::FrameTime::Now(); | 166 base::TimeTicks now = gfx::FrameTime::Now(); |
173 state->SetDouble("0_interval", | 167 timestamps_state->SetDouble( |
174 begin_impl_frame_args_.interval.InMicroseconds() / 1000.0L); | 168 "0_interval", begin_impl_frame_args_.interval.InMicroseconds() / 1000.0L); |
175 state->SetDouble( | 169 timestamps_state->SetDouble( |
176 "1_now_to_deadline", | 170 "1_now_to_deadline", |
177 (begin_impl_frame_args_.deadline - now).InMicroseconds() / 1000.0L); | 171 (begin_impl_frame_args_.deadline - now).InMicroseconds() / 1000.0L); |
178 state->SetDouble( | 172 timestamps_state->SetDouble( |
179 "2_frame_time_to_now", | 173 "2_frame_time_to_now", |
180 (now - begin_impl_frame_args_.frame_time).InMicroseconds() / 1000.0L); | 174 (now - begin_impl_frame_args_.frame_time).InMicroseconds() / 1000.0L); |
181 state->SetDouble("3_frame_time_to_deadline", | 175 timestamps_state->SetDouble( |
182 (begin_impl_frame_args_.deadline - | 176 "3_frame_time_to_deadline", |
183 begin_impl_frame_args_.frame_time).InMicroseconds() / | 177 (begin_impl_frame_args_.deadline - begin_impl_frame_args_.frame_time) |
184 1000.0L); | 178 .InMicroseconds() / |
185 state->SetDouble("4_now", | 179 1000.0L); |
186 (now - base::TimeTicks()).InMicroseconds() / 1000.0L); | 180 timestamps_state->SetDouble( |
187 state->SetDouble( | 181 "4_now", (now - base::TimeTicks()).InMicroseconds() / 1000.0L); |
| 182 timestamps_state->SetDouble( |
188 "5_frame_time", | 183 "5_frame_time", |
189 (begin_impl_frame_args_.frame_time - base::TimeTicks()).InMicroseconds() / | 184 (begin_impl_frame_args_.frame_time - base::TimeTicks()).InMicroseconds() / |
190 1000.0L); | 185 1000.0L); |
191 state->SetDouble( | 186 timestamps_state->SetDouble( |
192 "6_deadline", | 187 "6_deadline", |
193 (begin_impl_frame_args_.deadline - base::TimeTicks()).InMicroseconds() / | 188 (begin_impl_frame_args_.deadline - base::TimeTicks()).InMicroseconds() / |
194 1000.0L); | 189 1000.0L); |
195 state->EndDictionary(); | 190 state->Set("major_timestamps_in_ms", timestamps_state.release()); |
196 | 191 |
197 state->BeginDictionary("minor_state"); | 192 scoped_ptr<base::DictionaryValue> minor_state(new base::DictionaryValue); |
198 state->SetInteger("commit_count", commit_count_); | 193 minor_state->SetInteger("commit_count", commit_count_); |
199 state->SetInteger("current_frame_number", current_frame_number_); | 194 minor_state->SetInteger("current_frame_number", current_frame_number_); |
200 | 195 |
201 state->SetInteger("last_frame_number_animate_performed", | 196 minor_state->SetInteger("last_frame_number_animate_performed", |
202 last_frame_number_animate_performed_); | 197 last_frame_number_animate_performed_); |
203 state->SetInteger("last_frame_number_swap_performed", | 198 minor_state->SetInteger("last_frame_number_swap_performed", |
204 last_frame_number_swap_performed_); | 199 last_frame_number_swap_performed_); |
205 state->SetInteger("last_frame_number_swap_requested", | 200 minor_state->SetInteger("last_frame_number_swap_requested", |
206 last_frame_number_swap_requested_); | 201 last_frame_number_swap_requested_); |
207 state->SetInteger("last_frame_number_begin_main_frame_sent", | 202 minor_state->SetInteger( |
208 last_frame_number_begin_main_frame_sent_); | 203 "last_frame_number_begin_main_frame_sent", |
209 state->SetInteger("last_frame_number_update_visible_tiles_was_called", | 204 last_frame_number_begin_main_frame_sent_); |
210 last_frame_number_update_visible_tiles_was_called_); | 205 minor_state->SetInteger( |
| 206 "last_frame_number_update_visible_tiles_was_called", |
| 207 last_frame_number_update_visible_tiles_was_called_); |
211 | 208 |
212 state->SetInteger("manage_tiles_funnel", manage_tiles_funnel_); | 209 minor_state->SetInteger("manage_tiles_funnel", manage_tiles_funnel_); |
213 state->SetInteger("consecutive_checkerboard_animations", | 210 minor_state->SetInteger("consecutive_checkerboard_animations", |
214 consecutive_checkerboard_animations_); | 211 consecutive_checkerboard_animations_); |
215 state->SetInteger("max_pending_swaps_", max_pending_swaps_); | 212 minor_state->SetInteger("max_pending_swaps_", max_pending_swaps_); |
216 state->SetInteger("pending_swaps_", pending_swaps_); | 213 minor_state->SetInteger("pending_swaps_", pending_swaps_); |
217 state->SetBoolean("needs_redraw", needs_redraw_); | 214 minor_state->SetBoolean("needs_redraw", needs_redraw_); |
218 state->SetBoolean("needs_animate_", needs_animate_); | 215 minor_state->SetBoolean("needs_animate_", needs_animate_); |
219 state->SetBoolean("needs_manage_tiles", needs_manage_tiles_); | 216 minor_state->SetBoolean("needs_manage_tiles", needs_manage_tiles_); |
220 state->SetBoolean("swap_used_incomplete_tile", swap_used_incomplete_tile_); | 217 minor_state->SetBoolean("swap_used_incomplete_tile", |
221 state->SetBoolean("needs_commit", needs_commit_); | 218 swap_used_incomplete_tile_); |
222 state->SetBoolean("visible", visible_); | 219 minor_state->SetBoolean("needs_commit", needs_commit_); |
223 state->SetBoolean("can_start", can_start_); | 220 minor_state->SetBoolean("visible", visible_); |
224 state->SetBoolean("can_draw", can_draw_); | 221 minor_state->SetBoolean("can_start", can_start_); |
225 state->SetBoolean("has_pending_tree", has_pending_tree_); | 222 minor_state->SetBoolean("can_draw", can_draw_); |
226 state->SetBoolean("pending_tree_is_ready_for_activation", | 223 minor_state->SetBoolean("has_pending_tree", has_pending_tree_); |
227 pending_tree_is_ready_for_activation_); | 224 minor_state->SetBoolean("pending_tree_is_ready_for_activation", |
228 state->SetBoolean("active_tree_needs_first_draw", | 225 pending_tree_is_ready_for_activation_); |
229 active_tree_needs_first_draw_); | 226 minor_state->SetBoolean("active_tree_needs_first_draw", |
230 state->SetBoolean("did_create_and_initialize_first_output_surface", | 227 active_tree_needs_first_draw_); |
231 did_create_and_initialize_first_output_surface_); | 228 minor_state->SetBoolean("did_create_and_initialize_first_output_surface", |
232 state->SetBoolean("smoothness_takes_priority", smoothness_takes_priority_); | 229 did_create_and_initialize_first_output_surface_); |
233 state->SetBoolean("main_thread_is_in_high_latency_mode", | 230 minor_state->SetBoolean("smoothness_takes_priority", |
234 MainThreadIsInHighLatencyMode()); | 231 smoothness_takes_priority_); |
235 state->SetBoolean("skip_begin_main_frame_to_reduce_latency", | 232 minor_state->SetBoolean("main_thread_is_in_high_latency_mode", |
236 skip_begin_main_frame_to_reduce_latency_); | 233 MainThreadIsInHighLatencyMode()); |
237 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", | 234 minor_state->SetBoolean("skip_begin_main_frame_to_reduce_latency", |
238 skip_next_begin_main_frame_to_reduce_latency_); | 235 skip_begin_main_frame_to_reduce_latency_); |
239 state->SetBoolean("continuous_painting", continuous_painting_); | 236 minor_state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", |
240 state->EndDictionary(); | 237 skip_next_begin_main_frame_to_reduce_latency_); |
| 238 minor_state->SetBoolean("continuous_painting", continuous_painting_); |
| 239 state->Set("minor_state", minor_state.release()); |
| 240 |
| 241 return state.PassAs<base::Value>(); |
241 } | 242 } |
242 | 243 |
243 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { | 244 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { |
244 current_frame_number_++; | 245 current_frame_number_++; |
245 | 246 |
246 // "Drain" the ManageTiles funnel. | 247 // "Drain" the ManageTiles funnel. |
247 if (manage_tiles_funnel_ > 0) | 248 if (manage_tiles_funnel_ > 0) |
248 manage_tiles_funnel_--; | 249 manage_tiles_funnel_--; |
249 | 250 |
250 skip_begin_main_frame_to_reduce_latency_ = | 251 skip_begin_main_frame_to_reduce_latency_ = |
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
802 // BeginImplFrame. | 803 // BeginImplFrame. |
803 if (HasRequestedSwapThisFrame()) | 804 if (HasRequestedSwapThisFrame()) |
804 return true; | 805 return true; |
805 | 806 |
806 return false; | 807 return false; |
807 } | 808 } |
808 | 809 |
809 void SchedulerStateMachine::OnBeginImplFrame(const BeginFrameArgs& args) { | 810 void SchedulerStateMachine::OnBeginImplFrame(const BeginFrameArgs& args) { |
810 AdvanceCurrentFrameNumber(); | 811 AdvanceCurrentFrameNumber(); |
811 begin_impl_frame_args_ = args; | 812 begin_impl_frame_args_ = args; |
812 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE) | 813 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE) << *AsValue(); |
813 << AsValue()->ToString(); | |
814 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING; | 814 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING; |
815 } | 815 } |
816 | 816 |
817 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() { | 817 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() { |
818 DCHECK_EQ(begin_impl_frame_state_, | 818 DCHECK_EQ(begin_impl_frame_state_, |
819 BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) | 819 BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) |
820 << AsValue()->ToString(); | 820 << *AsValue(); |
821 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME; | 821 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME; |
822 } | 822 } |
823 | 823 |
824 void SchedulerStateMachine::OnBeginImplFrameDeadline() { | 824 void SchedulerStateMachine::OnBeginImplFrameDeadline() { |
825 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) | 825 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) |
826 << AsValue()->ToString(); | 826 << *AsValue(); |
827 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; | 827 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; |
828 } | 828 } |
829 | 829 |
830 void SchedulerStateMachine::OnBeginImplFrameIdle() { | 830 void SchedulerStateMachine::OnBeginImplFrameIdle() { |
831 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) | 831 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) |
832 << AsValue()->ToString(); | 832 << *AsValue(); |
833 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_IDLE; | 833 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_IDLE; |
834 } | 834 } |
835 | 835 |
836 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineEarly() const { | 836 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineEarly() const { |
837 // TODO(brianderson): This should take into account multiple commit sources. | 837 // TODO(brianderson): This should take into account multiple commit sources. |
838 | 838 |
839 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) | 839 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) |
840 return false; | 840 return false; |
841 | 841 |
842 // If we've lost the output surface, end the current BeginImplFrame ASAP | 842 // If we've lost the output surface, end the current BeginImplFrame ASAP |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 // removing textures (which might not). To be safe, request a commit | 1002 // removing textures (which might not). To be safe, request a commit |
1003 // anyway. | 1003 // anyway. |
1004 needs_commit_ = true; | 1004 needs_commit_ = true; |
1005 break; | 1005 break; |
1006 } | 1006 } |
1007 } | 1007 } |
1008 | 1008 |
1009 void SchedulerStateMachine::SetNeedsCommit() { needs_commit_ = true; } | 1009 void SchedulerStateMachine::SetNeedsCommit() { needs_commit_ = true; } |
1010 | 1010 |
1011 void SchedulerStateMachine::NotifyReadyToCommit() { | 1011 void SchedulerStateMachine::NotifyReadyToCommit() { |
1012 DCHECK(commit_state_ == COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED) | 1012 DCHECK(commit_state_ == COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED) << *AsValue(); |
1013 << AsValue()->ToString(); | |
1014 commit_state_ = COMMIT_STATE_READY_TO_COMMIT; | 1013 commit_state_ = COMMIT_STATE_READY_TO_COMMIT; |
1015 } | 1014 } |
1016 | 1015 |
1017 void SchedulerStateMachine::BeginMainFrameAborted(bool did_handle) { | 1016 void SchedulerStateMachine::BeginMainFrameAborted(bool did_handle) { |
1018 DCHECK_EQ(commit_state_, COMMIT_STATE_BEGIN_MAIN_FRAME_SENT); | 1017 DCHECK_EQ(commit_state_, COMMIT_STATE_BEGIN_MAIN_FRAME_SENT); |
1019 if (did_handle) { | 1018 if (did_handle) { |
1020 bool commit_was_aborted = true; | 1019 bool commit_was_aborted = true; |
1021 UpdateStateOnCommit(commit_was_aborted); | 1020 UpdateStateOnCommit(commit_was_aborted); |
1022 } else { | 1021 } else { |
1023 commit_state_ = COMMIT_STATE_IDLE; | 1022 commit_state_ = COMMIT_STATE_IDLE; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1071 case OUTPUT_SURFACE_ACTIVE: | 1070 case OUTPUT_SURFACE_ACTIVE: |
1072 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: | 1071 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: |
1073 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: | 1072 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: |
1074 return true; | 1073 return true; |
1075 } | 1074 } |
1076 NOTREACHED(); | 1075 NOTREACHED(); |
1077 return false; | 1076 return false; |
1078 } | 1077 } |
1079 | 1078 |
1080 } // namespace cc | 1079 } // namespace cc |
OLD | NEW |