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/format_macros.h" | 8 #include "base/format_macros.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
11 #include "base/values.h" | 11 #include "base/values.h" |
12 #include "ui/gfx/frame_time.h" | 12 #include "ui/gfx/frame_time.h" |
13 | 13 |
14 namespace cc { | 14 namespace cc { |
15 | 15 |
16 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) | 16 SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) |
17 : settings_(settings), | 17 : settings_(settings), |
18 output_surface_state_(OUTPUT_SURFACE_LOST), | 18 output_surface_state_(OUTPUT_SURFACE_LOST), |
19 begin_impl_frame_state_(BEGIN_IMPL_FRAME_STATE_IDLE), | 19 begin_impl_frame_state_(BEGIN_IMPL_FRAME_STATE_IDLE), |
20 commit_state_(COMMIT_STATE_IDLE), | 20 commit_state_(COMMIT_STATE_IDLE), |
21 texture_state_(LAYER_TEXTURE_STATE_UNLOCKED), | 21 texture_state_(LAYER_TEXTURE_STATE_UNLOCKED), |
22 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), | 22 forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), |
23 readback_state_(READBACK_STATE_IDLE), | 23 readback_state_(READBACK_STATE_IDLE), |
24 commit_count_(0), | 24 commit_count_(0), |
25 current_frame_number_(0), | 25 current_frame_number_(0), |
26 last_frame_number_swap_performed_(-1), | 26 last_frame_number_swap_performed_(-1), |
27 last_frame_number_begin_main_frame_sent_(-1), | 27 last_frame_number_begin_main_frame_sent_(-1), |
28 last_frame_number_update_visible_tiles_was_called_(-1), | 28 last_frame_number_update_visible_tiles_was_called_(-1), |
29 last_frame_number_manage_tiles_called_(-1), | 29 manage_tiles_funnel_(0), |
30 consecutive_failed_draws_(0), | 30 consecutive_failed_draws_(0), |
31 needs_redraw_(false), | 31 needs_redraw_(false), |
32 needs_manage_tiles_(false), | 32 needs_manage_tiles_(false), |
33 swap_used_incomplete_tile_(false), | 33 swap_used_incomplete_tile_(false), |
34 needs_commit_(false), | 34 needs_commit_(false), |
35 main_thread_needs_layer_textures_(false), | 35 main_thread_needs_layer_textures_(false), |
36 inside_poll_for_anticipated_draw_triggers_(false), | 36 inside_poll_for_anticipated_draw_triggers_(false), |
37 visible_(false), | 37 visible_(false), |
38 can_start_(false), | 38 can_start_(false), |
39 can_draw_(false), | 39 can_draw_(false), |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 | 232 |
233 minor_state->SetInteger("last_frame_number_swap_performed", | 233 minor_state->SetInteger("last_frame_number_swap_performed", |
234 last_frame_number_swap_performed_); | 234 last_frame_number_swap_performed_); |
235 minor_state->SetInteger( | 235 minor_state->SetInteger( |
236 "last_frame_number_begin_main_frame_sent", | 236 "last_frame_number_begin_main_frame_sent", |
237 last_frame_number_begin_main_frame_sent_); | 237 last_frame_number_begin_main_frame_sent_); |
238 minor_state->SetInteger( | 238 minor_state->SetInteger( |
239 "last_frame_number_update_visible_tiles_was_called", | 239 "last_frame_number_update_visible_tiles_was_called", |
240 last_frame_number_update_visible_tiles_was_called_); | 240 last_frame_number_update_visible_tiles_was_called_); |
241 | 241 |
| 242 minor_state->SetInteger("manage_tiles_funnel", manage_tiles_funnel_); |
242 minor_state->SetInteger("consecutive_failed_draws", | 243 minor_state->SetInteger("consecutive_failed_draws", |
243 consecutive_failed_draws_); | 244 consecutive_failed_draws_); |
244 minor_state->SetBoolean("needs_redraw", needs_redraw_); | 245 minor_state->SetBoolean("needs_redraw", needs_redraw_); |
245 minor_state->SetBoolean("needs_manage_tiles", needs_manage_tiles_); | 246 minor_state->SetBoolean("needs_manage_tiles", needs_manage_tiles_); |
246 minor_state->SetBoolean("swap_used_incomplete_tile", | 247 minor_state->SetBoolean("swap_used_incomplete_tile", |
247 swap_used_incomplete_tile_); | 248 swap_used_incomplete_tile_); |
248 minor_state->SetBoolean("needs_commit", needs_commit_); | 249 minor_state->SetBoolean("needs_commit", needs_commit_); |
249 minor_state->SetBoolean("main_thread_needs_layer_textures", | 250 minor_state->SetBoolean("main_thread_needs_layer_textures", |
250 main_thread_needs_layer_textures_); | 251 main_thread_needs_layer_textures_); |
251 minor_state->SetBoolean("visible", visible_); | 252 minor_state->SetBoolean("visible", visible_); |
(...skipping 11 matching lines...) Expand all Loading... |
263 smoothness_takes_priority_); | 264 smoothness_takes_priority_); |
264 minor_state->SetBoolean("main_thread_is_in_high_latency_mode", | 265 minor_state->SetBoolean("main_thread_is_in_high_latency_mode", |
265 MainThreadIsInHighLatencyMode()); | 266 MainThreadIsInHighLatencyMode()); |
266 minor_state->SetBoolean("skip_begin_main_frame_to_reduce_latency", | 267 minor_state->SetBoolean("skip_begin_main_frame_to_reduce_latency", |
267 skip_begin_main_frame_to_reduce_latency_); | 268 skip_begin_main_frame_to_reduce_latency_); |
268 state->Set("minor_state", minor_state.release()); | 269 state->Set("minor_state", minor_state.release()); |
269 | 270 |
270 return state.PassAs<base::Value>(); | 271 return state.PassAs<base::Value>(); |
271 } | 272 } |
272 | 273 |
| 274 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { |
| 275 current_frame_number_++; |
| 276 |
| 277 // "Drain" the ManageTiles funnel. |
| 278 if (manage_tiles_funnel_ > 0) |
| 279 manage_tiles_funnel_--; |
| 280 } |
| 281 |
273 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const { | 282 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const { |
274 return current_frame_number_ == | 283 return current_frame_number_ == |
275 last_frame_number_begin_main_frame_sent_; | 284 last_frame_number_begin_main_frame_sent_; |
276 } | 285 } |
277 | 286 |
278 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const { | 287 bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const { |
279 return current_frame_number_ == | 288 return current_frame_number_ == |
280 last_frame_number_update_visible_tiles_was_called_; | 289 last_frame_number_update_visible_tiles_was_called_; |
281 } | 290 } |
282 | 291 |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
500 bool SchedulerStateMachine::ShouldCommit() const { | 509 bool SchedulerStateMachine::ShouldCommit() const { |
501 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT; | 510 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT; |
502 } | 511 } |
503 | 512 |
504 bool SchedulerStateMachine::IsCommitStateWaiting() const { | 513 bool SchedulerStateMachine::IsCommitStateWaiting() const { |
505 return commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS; | 514 return commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS; |
506 } | 515 } |
507 | 516 |
508 bool SchedulerStateMachine::ShouldManageTiles() const { | 517 bool SchedulerStateMachine::ShouldManageTiles() const { |
509 // ManageTiles only really needs to be called immediately after commit | 518 // ManageTiles only really needs to be called immediately after commit |
510 // and then periodically after that. Limiting to once per frame prevents | 519 // and then periodically after that. Use a funnel to make sure we average |
511 // post-commit and post-draw ManageTiles on the same frame. | 520 // one ManageTiles per BeginImplFrame in the long run. |
512 if (last_frame_number_manage_tiles_called_ == current_frame_number_) | 521 if (manage_tiles_funnel_ > 0) |
513 return false; | 522 return false; |
514 | 523 |
515 // Limiting to once per-frame is not enough, since we only want to | 524 // Limiting to once per-frame is not enough, since we only want to |
516 // manage tiles _after_ draws. Polling for draw triggers and | 525 // manage tiles _after_ draws. Polling for draw triggers and |
517 // begin-frame are mutually exclusive, so we limit to these two cases. | 526 // begin-frame are mutually exclusive, so we limit to these two cases. |
518 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && | 527 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && |
519 !inside_poll_for_anticipated_draw_triggers_) | 528 !inside_poll_for_anticipated_draw_triggers_) |
520 return false; | 529 return false; |
521 return needs_manage_tiles_; | 530 return needs_manage_tiles_; |
522 } | 531 } |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
878 // SetNeedsBeginImplFrame requests, which may propagate to the BeginImplFrame | 887 // SetNeedsBeginImplFrame requests, which may propagate to the BeginImplFrame |
879 // provider and get sampled at an inopportune time, delaying the next | 888 // provider and get sampled at an inopportune time, delaying the next |
880 // BeginImplFrame. | 889 // BeginImplFrame. |
881 if (last_frame_number_swap_performed_ == current_frame_number_) | 890 if (last_frame_number_swap_performed_ == current_frame_number_) |
882 return true; | 891 return true; |
883 | 892 |
884 return false; | 893 return false; |
885 } | 894 } |
886 | 895 |
887 void SchedulerStateMachine::OnBeginImplFrame(const BeginFrameArgs& args) { | 896 void SchedulerStateMachine::OnBeginImplFrame(const BeginFrameArgs& args) { |
888 current_frame_number_++; | 897 AdvanceCurrentFrameNumber(); |
889 last_begin_impl_frame_args_ = args; | 898 last_begin_impl_frame_args_ = args; |
890 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE) << *AsValue(); | 899 DCHECK_EQ(begin_impl_frame_state_, BEGIN_IMPL_FRAME_STATE_IDLE) << *AsValue(); |
891 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING; | 900 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING; |
892 } | 901 } |
893 | 902 |
894 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() { | 903 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() { |
895 DCHECK_EQ(begin_impl_frame_state_, | 904 DCHECK_EQ(begin_impl_frame_state_, |
896 BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) | 905 BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) |
897 << *AsValue(); | 906 << *AsValue(); |
898 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME; | 907 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME; |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
974 last_frame_number_swap_performed_ == current_frame_number_) && | 983 last_frame_number_swap_performed_ == current_frame_number_) && |
975 last_frame_number_begin_main_frame_sent_ != current_frame_number_; | 984 last_frame_number_begin_main_frame_sent_ != current_frame_number_; |
976 } | 985 } |
977 | 986 |
978 // If the active tree needs its first draw in any other state, we know the | 987 // If the active tree needs its first draw in any other state, we know the |
979 // main thread is in a high latency mode. | 988 // main thread is in a high latency mode. |
980 return active_tree_needs_first_draw_; | 989 return active_tree_needs_first_draw_; |
981 } | 990 } |
982 | 991 |
983 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() { | 992 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() { |
984 current_frame_number_++; | 993 AdvanceCurrentFrameNumber(); |
985 inside_poll_for_anticipated_draw_triggers_ = true; | 994 inside_poll_for_anticipated_draw_triggers_ = true; |
986 } | 995 } |
987 | 996 |
988 void SchedulerStateMachine::DidLeavePollForAnticipatedDrawTriggers() { | 997 void SchedulerStateMachine::DidLeavePollForAnticipatedDrawTriggers() { |
989 inside_poll_for_anticipated_draw_triggers_ = false; | 998 inside_poll_for_anticipated_draw_triggers_ = false; |
990 } | 999 } |
991 | 1000 |
992 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } | 1001 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } |
993 | 1002 |
994 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; } | 1003 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; } |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1074 UpdateStateOnCommit(commit_was_aborted); | 1083 UpdateStateOnCommit(commit_was_aborted); |
1075 } else { | 1084 } else { |
1076 DCHECK_NE(readback_state_, READBACK_STATE_WAITING_FOR_COMMIT); | 1085 DCHECK_NE(readback_state_, READBACK_STATE_WAITING_FOR_COMMIT); |
1077 commit_state_ = COMMIT_STATE_IDLE; | 1086 commit_state_ = COMMIT_STATE_IDLE; |
1078 SetNeedsCommit(); | 1087 SetNeedsCommit(); |
1079 } | 1088 } |
1080 } | 1089 } |
1081 | 1090 |
1082 void SchedulerStateMachine::DidManageTiles() { | 1091 void SchedulerStateMachine::DidManageTiles() { |
1083 needs_manage_tiles_ = false; | 1092 needs_manage_tiles_ = false; |
1084 last_frame_number_manage_tiles_called_ = current_frame_number_; | 1093 // "Fill" the ManageTiles funnel. |
| 1094 manage_tiles_funnel_++; |
1085 } | 1095 } |
1086 | 1096 |
1087 void SchedulerStateMachine::DidLoseOutputSurface() { | 1097 void SchedulerStateMachine::DidLoseOutputSurface() { |
1088 if (output_surface_state_ == OUTPUT_SURFACE_LOST || | 1098 if (output_surface_state_ == OUTPUT_SURFACE_LOST || |
1089 output_surface_state_ == OUTPUT_SURFACE_CREATING) | 1099 output_surface_state_ == OUTPUT_SURFACE_CREATING) |
1090 return; | 1100 return; |
1091 output_surface_state_ = OUTPUT_SURFACE_LOST; | 1101 output_surface_state_ = OUTPUT_SURFACE_LOST; |
1092 needs_redraw_ = false; | 1102 needs_redraw_ = false; |
1093 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_IDLE; | 1103 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_IDLE; |
1094 } | 1104 } |
(...skipping 24 matching lines...) Expand all Loading... |
1119 case OUTPUT_SURFACE_ACTIVE: | 1129 case OUTPUT_SURFACE_ACTIVE: |
1120 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: | 1130 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: |
1121 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: | 1131 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: |
1122 return true; | 1132 return true; |
1123 } | 1133 } |
1124 NOTREACHED(); | 1134 NOTREACHED(); |
1125 return false; | 1135 return false; |
1126 } | 1136 } |
1127 | 1137 |
1128 } // namespace cc | 1138 } // namespace cc |
OLD | NEW |