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/format_macros.h" | 7 #include "base/format_macros.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/strings/stringprintf.h" | 9 #include "base/strings/stringprintf.h" |
10 #include "base/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 needs_prepare_tiles_(false), | 44 needs_prepare_tiles_(false), |
45 needs_begin_main_frame_(false), | 45 needs_begin_main_frame_(false), |
46 needs_one_begin_impl_frame_(false), | 46 needs_one_begin_impl_frame_(false), |
47 visible_(false), | 47 visible_(false), |
48 resourceless_draw_(false), | 48 resourceless_draw_(false), |
49 can_draw_(false), | 49 can_draw_(false), |
50 has_pending_tree_(false), | 50 has_pending_tree_(false), |
51 pending_tree_is_ready_for_activation_(false), | 51 pending_tree_is_ready_for_activation_(false), |
52 active_tree_needs_first_draw_(false), | 52 active_tree_needs_first_draw_(false), |
53 did_create_and_initialize_first_output_surface_(false), | 53 did_create_and_initialize_first_output_surface_(false), |
54 impl_latency_takes_priority_(false), | 54 tree_priority_(NEW_CONTENT_TAKES_PRIORITY), |
| 55 scroll_handler_state_( |
| 56 ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER), |
| 57 critical_begin_main_frame_to_activate_is_fast_(true), |
55 main_thread_missed_last_deadline_(false), | 58 main_thread_missed_last_deadline_(false), |
56 skip_next_begin_main_frame_to_reduce_latency_(false), | 59 skip_next_begin_main_frame_to_reduce_latency_(false), |
57 children_need_begin_frames_(false), | 60 children_need_begin_frames_(false), |
58 defer_commits_(false), | 61 defer_commits_(false), |
59 video_needs_begin_frames_(false), | 62 video_needs_begin_frames_(false), |
60 last_commit_had_no_updates_(false), | 63 last_commit_had_no_updates_(false), |
61 wait_for_ready_to_draw_(false), | 64 wait_for_ready_to_draw_(false), |
62 did_request_swap_in_last_frame_(false), | 65 did_request_swap_in_last_frame_(false), |
63 did_perform_swap_in_last_draw_(false) {} | 66 did_perform_swap_in_last_draw_(false) {} |
64 | 67 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 return "FORCED_REDRAW_STATE_WAITING_FOR_COMMIT"; | 146 return "FORCED_REDRAW_STATE_WAITING_FOR_COMMIT"; |
144 case FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION: | 147 case FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION: |
145 return "FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION"; | 148 return "FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION"; |
146 case FORCED_REDRAW_STATE_WAITING_FOR_DRAW: | 149 case FORCED_REDRAW_STATE_WAITING_FOR_DRAW: |
147 return "FORCED_REDRAW_STATE_WAITING_FOR_DRAW"; | 150 return "FORCED_REDRAW_STATE_WAITING_FOR_DRAW"; |
148 } | 151 } |
149 NOTREACHED(); | 152 NOTREACHED(); |
150 return "???"; | 153 return "???"; |
151 } | 154 } |
152 | 155 |
| 156 const char* ScrollHandlerStateToString(ScrollHandlerState state) { |
| 157 switch (state) { |
| 158 case ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER: |
| 159 return "SCROLL_AFFECTS_SCROLL_HANDLER"; |
| 160 case ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER: |
| 161 return "SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER"; |
| 162 } |
| 163 NOTREACHED(); |
| 164 return "???"; |
| 165 } |
| 166 |
153 const char* SchedulerStateMachine::ActionToString(Action action) { | 167 const char* SchedulerStateMachine::ActionToString(Action action) { |
154 switch (action) { | 168 switch (action) { |
155 case ACTION_NONE: | 169 case ACTION_NONE: |
156 return "ACTION_NONE"; | 170 return "ACTION_NONE"; |
157 case ACTION_ANIMATE: | 171 case ACTION_ANIMATE: |
158 return "ACTION_ANIMATE"; | 172 return "ACTION_ANIMATE"; |
159 case ACTION_SEND_BEGIN_MAIN_FRAME: | 173 case ACTION_SEND_BEGIN_MAIN_FRAME: |
160 return "ACTION_SEND_BEGIN_MAIN_FRAME"; | 174 return "ACTION_SEND_BEGIN_MAIN_FRAME"; |
161 case ACTION_COMMIT: | 175 case ACTION_COMMIT: |
162 return "ACTION_COMMIT"; | 176 return "ACTION_COMMIT"; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 state->SetBoolean("can_draw", can_draw_); | 247 state->SetBoolean("can_draw", can_draw_); |
234 state->SetBoolean("resourceless_draw", resourceless_draw_); | 248 state->SetBoolean("resourceless_draw", resourceless_draw_); |
235 state->SetBoolean("has_pending_tree", has_pending_tree_); | 249 state->SetBoolean("has_pending_tree", has_pending_tree_); |
236 state->SetBoolean("pending_tree_is_ready_for_activation", | 250 state->SetBoolean("pending_tree_is_ready_for_activation", |
237 pending_tree_is_ready_for_activation_); | 251 pending_tree_is_ready_for_activation_); |
238 state->SetBoolean("active_tree_needs_first_draw", | 252 state->SetBoolean("active_tree_needs_first_draw", |
239 active_tree_needs_first_draw_); | 253 active_tree_needs_first_draw_); |
240 state->SetBoolean("wait_for_ready_to_draw", wait_for_ready_to_draw_); | 254 state->SetBoolean("wait_for_ready_to_draw", wait_for_ready_to_draw_); |
241 state->SetBoolean("did_create_and_initialize_first_output_surface", | 255 state->SetBoolean("did_create_and_initialize_first_output_surface", |
242 did_create_and_initialize_first_output_surface_); | 256 did_create_and_initialize_first_output_surface_); |
243 state->SetBoolean("impl_latency_takes_priority", | 257 state->SetString("tree_priority", TreePriorityToString(tree_priority_)); |
244 impl_latency_takes_priority_); | 258 state->SetString("scroll_handler_state", |
| 259 ScrollHandlerStateToString(scroll_handler_state_)); |
| 260 state->SetBoolean("critical_begin_main_frame_to_activate_is_fast_", |
| 261 critical_begin_main_frame_to_activate_is_fast_); |
245 state->SetBoolean("main_thread_missed_last_deadline", | 262 state->SetBoolean("main_thread_missed_last_deadline", |
246 main_thread_missed_last_deadline_); | 263 main_thread_missed_last_deadline_); |
247 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", | 264 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", |
248 skip_next_begin_main_frame_to_reduce_latency_); | 265 skip_next_begin_main_frame_to_reduce_latency_); |
249 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_); | 266 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_); |
250 state->SetBoolean("video_needs_begin_frames", video_needs_begin_frames_); | 267 state->SetBoolean("video_needs_begin_frames", video_needs_begin_frames_); |
251 state->SetBoolean("defer_commits", defer_commits_); | 268 state->SetBoolean("defer_commits", defer_commits_); |
252 state->SetBoolean("last_commit_had_no_updates", last_commit_had_no_updates_); | 269 state->SetBoolean("last_commit_had_no_updates", last_commit_had_no_updates_); |
253 state->SetBoolean("did_request_swap_in_last_frame", | 270 state->SetBoolean("did_request_swap_in_last_frame", |
254 did_request_swap_in_last_frame_); | 271 did_request_swap_in_last_frame_); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 return false; | 445 return false; |
429 | 446 |
430 // Only send BeginMainFrame when there isn't another commit pending already. | 447 // Only send BeginMainFrame when there isn't another commit pending already. |
431 // Other parts of the state machine indirectly defer the BeginMainFrame | 448 // Other parts of the state machine indirectly defer the BeginMainFrame |
432 // by transitioning to WAITING commit states rather than going | 449 // by transitioning to WAITING commit states rather than going |
433 // immediately to IDLE. | 450 // immediately to IDLE. |
434 if (begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_IDLE) | 451 if (begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_IDLE) |
435 return false; | 452 return false; |
436 | 453 |
437 // Don't send BeginMainFrame early if we are prioritizing the active tree | 454 // Don't send BeginMainFrame early if we are prioritizing the active tree |
438 // because of impl_latency_takes_priority_. | 455 // because of ImplLatencyTakesPriority. |
439 if (impl_latency_takes_priority_ && | 456 if (ImplLatencyTakesPriority() && |
440 (has_pending_tree_ || active_tree_needs_first_draw_)) { | 457 (has_pending_tree_ || active_tree_needs_first_draw_)) { |
441 return false; | 458 return false; |
442 } | 459 } |
443 | 460 |
444 // We should not send BeginMainFrame while we are in the idle state since we | 461 // We should not send BeginMainFrame while we are in the idle state since we |
445 // might have new user input arriving soon. It's okay to send BeginMainFrame | 462 // might have new user input arriving soon. It's okay to send BeginMainFrame |
446 // for the synchronous compositor because the main thread is always high | 463 // for the synchronous compositor because the main thread is always high |
447 // latency in that case. | 464 // latency in that case. |
448 // TODO(brianderson): Allow sending BeginMainFrame while idle when the main | 465 // TODO(brianderson): Allow sending BeginMainFrame while idle when the main |
449 // thread isn't consuming user input for non-synchronous compositor. | 466 // thread isn't consuming user input for non-synchronous compositor. |
(...skipping 15 matching lines...) Expand all Loading... |
465 return false; | 482 return false; |
466 | 483 |
467 // Make sure the BeginMainFrame can finish eventually if we start it. | 484 // Make sure the BeginMainFrame can finish eventually if we start it. |
468 if (SendingBeginMainFrameMightCauseDeadlock()) | 485 if (SendingBeginMainFrameMightCauseDeadlock()) |
469 return false; | 486 return false; |
470 | 487 |
471 if (!settings_.main_frame_while_swap_throttled_enabled) { | 488 if (!settings_.main_frame_while_swap_throttled_enabled) { |
472 // SwapAck throttle the BeginMainFrames unless we just swapped to | 489 // SwapAck throttle the BeginMainFrames unless we just swapped to |
473 // potentially improve impl-thread latency over main-thread throughput. | 490 // potentially improve impl-thread latency over main-thread throughput. |
474 // TODO(brianderson): Remove this restriction to improve throughput or | 491 // TODO(brianderson): Remove this restriction to improve throughput or |
475 // make it conditional on impl_latency_takes_priority_. | 492 // make it conditional on ImplLatencyTakesPriority. |
476 bool just_swapped_in_deadline = | 493 bool just_swapped_in_deadline = |
477 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && | 494 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && |
478 did_perform_swap_in_last_draw_; | 495 did_perform_swap_in_last_draw_; |
479 if (SwapThrottled() && !just_swapped_in_deadline) | 496 if (SwapThrottled() && !just_swapped_in_deadline) |
480 return false; | 497 return false; |
481 } | 498 } |
482 | 499 |
483 if (skip_next_begin_main_frame_to_reduce_latency_) | 500 if (skip_next_begin_main_frame_to_reduce_latency_) |
484 return false; | 501 return false; |
485 | 502 |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
896 | 913 |
897 // This is used to prioritize impl-thread draws when the main thread isn't | 914 // This is used to prioritize impl-thread draws when the main thread isn't |
898 // producing anything, e.g., after an aborted commit. We also check that we | 915 // producing anything, e.g., after an aborted commit. We also check that we |
899 // don't have a pending tree -- otherwise we should give it a chance to | 916 // don't have a pending tree -- otherwise we should give it a chance to |
900 // activate. | 917 // activate. |
901 // TODO(skyostil): Revisit this when we have more accurate deadline estimates. | 918 // TODO(skyostil): Revisit this when we have more accurate deadline estimates. |
902 if (begin_main_frame_state_ == BEGIN_MAIN_FRAME_STATE_IDLE && | 919 if (begin_main_frame_state_ == BEGIN_MAIN_FRAME_STATE_IDLE && |
903 !has_pending_tree_) | 920 !has_pending_tree_) |
904 return true; | 921 return true; |
905 | 922 |
906 // Prioritize impl-thread draws in impl_latency_takes_priority_ mode. | 923 // Prioritize impl-thread draws in ImplLatencyTakesPriority mode. |
907 if (impl_latency_takes_priority_) | 924 if (ImplLatencyTakesPriority()) |
908 return true; | 925 return true; |
909 | 926 |
910 return false; | 927 return false; |
911 } | 928 } |
912 | 929 |
913 bool SchedulerStateMachine::main_thread_missed_last_deadline() const { | 930 bool SchedulerStateMachine::main_thread_missed_last_deadline() const { |
914 return main_thread_missed_last_deadline_; | 931 return main_thread_missed_last_deadline_; |
915 } | 932 } |
916 | 933 |
917 bool SchedulerStateMachine::SwapThrottled() const { | 934 bool SchedulerStateMachine::SwapThrottled() const { |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
969 | 986 |
970 did_perform_swap_in_last_draw_ = true; | 987 did_perform_swap_in_last_draw_ = true; |
971 last_frame_number_swap_performed_ = current_frame_number_; | 988 last_frame_number_swap_performed_ = current_frame_number_; |
972 } | 989 } |
973 | 990 |
974 void SchedulerStateMachine::DidSwapBuffersComplete() { | 991 void SchedulerStateMachine::DidSwapBuffersComplete() { |
975 TRACE_EVENT_ASYNC_END0("cc", "Scheduler:pending_swaps", this); | 992 TRACE_EVENT_ASYNC_END0("cc", "Scheduler:pending_swaps", this); |
976 pending_swaps_--; | 993 pending_swaps_--; |
977 } | 994 } |
978 | 995 |
979 void SchedulerStateMachine::SetImplLatencyTakesPriority( | 996 void SchedulerStateMachine::SetTreePrioritiesAndScrollState( |
980 bool impl_latency_takes_priority) { | 997 TreePriority tree_priority, |
981 impl_latency_takes_priority_ = impl_latency_takes_priority; | 998 ScrollHandlerState scroll_handler_state) { |
| 999 tree_priority_ = tree_priority; |
| 1000 scroll_handler_state_ = scroll_handler_state; |
| 1001 } |
| 1002 |
| 1003 void SchedulerStateMachine::SetCriticalBeginMainFrameToActivateIsFast( |
| 1004 bool is_fast) { |
| 1005 critical_begin_main_frame_to_activate_is_fast_ = is_fast; |
| 1006 } |
| 1007 |
| 1008 bool SchedulerStateMachine::ImplLatencyTakesPriority() const { |
| 1009 // Attempt to synchronize with the main thread if it has a scroll listener |
| 1010 // and is fast. |
| 1011 if (ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER == |
| 1012 scroll_handler_state_ && |
| 1013 critical_begin_main_frame_to_activate_is_fast_) |
| 1014 return false; |
| 1015 |
| 1016 // Don't wait for the main thread if we are prioritizing smoothness. |
| 1017 if (SMOOTHNESS_TAKES_PRIORITY == tree_priority_) |
| 1018 return true; |
| 1019 |
| 1020 return false; |
982 } | 1021 } |
983 | 1022 |
984 void SchedulerStateMachine::DidDrawIfPossibleCompleted(DrawResult result) { | 1023 void SchedulerStateMachine::DidDrawIfPossibleCompleted(DrawResult result) { |
985 switch (result) { | 1024 switch (result) { |
986 case INVALID_RESULT: | 1025 case INVALID_RESULT: |
987 NOTREACHED() << "Uninitialized DrawResult."; | 1026 NOTREACHED() << "Uninitialized DrawResult."; |
988 break; | 1027 break; |
989 case DRAW_ABORTED_CANT_DRAW: | 1028 case DRAW_ABORTED_CANT_DRAW: |
990 case DRAW_ABORTED_CONTEXT_LOST: | 1029 case DRAW_ABORTED_CONTEXT_LOST: |
991 NOTREACHED() << "Invalid return value from DrawAndSwapIfPossible:" | 1030 NOTREACHED() << "Invalid return value from DrawAndSwapIfPossible:" |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1112 case OUTPUT_SURFACE_ACTIVE: | 1151 case OUTPUT_SURFACE_ACTIVE: |
1113 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: | 1152 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: |
1114 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: | 1153 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: |
1115 return true; | 1154 return true; |
1116 } | 1155 } |
1117 NOTREACHED(); | 1156 NOTREACHED(); |
1118 return false; | 1157 return false; |
1119 } | 1158 } |
1120 | 1159 |
1121 } // namespace cc | 1160 } // namespace cc |
OLD | NEW |