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