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 smoothness_takes_priority_(false), |
| 51 scroll_affects_scroll_handler_(false), |
| 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 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
230 state->SetBoolean("can_draw", can_draw_); | 232 state->SetBoolean("can_draw", can_draw_); |
231 state->SetBoolean("resourceless_draw", resourceless_draw_); | 233 state->SetBoolean("resourceless_draw", resourceless_draw_); |
232 state->SetBoolean("has_pending_tree", has_pending_tree_); | 234 state->SetBoolean("has_pending_tree", has_pending_tree_); |
233 state->SetBoolean("pending_tree_is_ready_for_activation", | 235 state->SetBoolean("pending_tree_is_ready_for_activation", |
234 pending_tree_is_ready_for_activation_); | 236 pending_tree_is_ready_for_activation_); |
235 state->SetBoolean("active_tree_needs_first_draw", | 237 state->SetBoolean("active_tree_needs_first_draw", |
236 active_tree_needs_first_draw_); | 238 active_tree_needs_first_draw_); |
237 state->SetBoolean("wait_for_ready_to_draw", wait_for_ready_to_draw_); | 239 state->SetBoolean("wait_for_ready_to_draw", wait_for_ready_to_draw_); |
238 state->SetBoolean("did_create_and_initialize_first_output_surface", | 240 state->SetBoolean("did_create_and_initialize_first_output_surface", |
239 did_create_and_initialize_first_output_surface_); | 241 did_create_and_initialize_first_output_surface_); |
240 state->SetBoolean("impl_latency_takes_priority", | 242 state->SetBoolean("smoothness_takes_priority", smoothness_takes_priority_); |
241 impl_latency_takes_priority_); | 243 state->SetBoolean("scroll_affects_scroll_handler", |
| 244 scroll_affects_scroll_handler_); |
| 245 state->SetBoolean("critical_begin_main_frame_to_activate_is_fast_", |
| 246 critical_begin_main_frame_to_activate_is_fast_); |
242 state->SetBoolean("main_thread_missed_last_deadline", | 247 state->SetBoolean("main_thread_missed_last_deadline", |
243 main_thread_missed_last_deadline_); | 248 main_thread_missed_last_deadline_); |
244 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", | 249 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", |
245 skip_next_begin_main_frame_to_reduce_latency_); | 250 skip_next_begin_main_frame_to_reduce_latency_); |
246 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_); | 251 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_); |
247 state->SetBoolean("video_needs_begin_frames", video_needs_begin_frames_); | 252 state->SetBoolean("video_needs_begin_frames", video_needs_begin_frames_); |
248 state->SetBoolean("defer_commits", defer_commits_); | 253 state->SetBoolean("defer_commits", defer_commits_); |
249 state->SetBoolean("last_commit_had_no_updates", last_commit_had_no_updates_); | 254 state->SetBoolean("last_commit_had_no_updates", last_commit_had_no_updates_); |
250 state->SetBoolean("did_request_swap_in_last_frame", | 255 state->SetBoolean("did_request_swap_in_last_frame", |
251 did_request_swap_in_last_frame_); | 256 did_request_swap_in_last_frame_); |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 return false; | 430 return false; |
426 | 431 |
427 // Only send BeginMainFrame when there isn't another commit pending already. | 432 // Only send BeginMainFrame when there isn't another commit pending already. |
428 // Other parts of the state machine indirectly defer the BeginMainFrame | 433 // Other parts of the state machine indirectly defer the BeginMainFrame |
429 // by transitioning to WAITING commit states rather than going | 434 // by transitioning to WAITING commit states rather than going |
430 // immediately to IDLE. | 435 // immediately to IDLE. |
431 if (begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_IDLE) | 436 if (begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_IDLE) |
432 return false; | 437 return false; |
433 | 438 |
434 // Don't send BeginMainFrame early if we are prioritizing the active tree | 439 // Don't send BeginMainFrame early if we are prioritizing the active tree |
435 // because of impl_latency_takes_priority_. | 440 // because of ImplLatencyTakesPriority. |
436 if (impl_latency_takes_priority_ && | 441 if (ImplLatencyTakesPriority() && |
437 (has_pending_tree_ || active_tree_needs_first_draw_)) { | 442 (has_pending_tree_ || active_tree_needs_first_draw_)) { |
438 return false; | 443 return false; |
439 } | 444 } |
440 | 445 |
441 // We should not send BeginMainFrame while we are in the idle state since we | 446 // 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 | 447 // 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 | 448 // for the synchronous compositor because the main thread is always high |
444 // latency in that case. | 449 // latency in that case. |
445 // TODO(brianderson): Allow sending BeginMainFrame while idle when the main | 450 // TODO(brianderson): Allow sending BeginMainFrame while idle when the main |
446 // thread isn't consuming user input for non-synchronous compositor. | 451 // thread isn't consuming user input for non-synchronous compositor. |
(...skipping 15 matching lines...) Expand all Loading... |
462 return false; | 467 return false; |
463 | 468 |
464 // Make sure the BeginMainFrame can finish eventually if we start it. | 469 // Make sure the BeginMainFrame can finish eventually if we start it. |
465 if (SendingBeginMainFrameMightCauseDeadlock()) | 470 if (SendingBeginMainFrameMightCauseDeadlock()) |
466 return false; | 471 return false; |
467 | 472 |
468 if (!settings_.main_frame_while_swap_throttled_enabled) { | 473 if (!settings_.main_frame_while_swap_throttled_enabled) { |
469 // SwapAck throttle the BeginMainFrames unless we just swapped to | 474 // SwapAck throttle the BeginMainFrames unless we just swapped to |
470 // potentially improve impl-thread latency over main-thread throughput. | 475 // potentially improve impl-thread latency over main-thread throughput. |
471 // TODO(brianderson): Remove this restriction to improve throughput or | 476 // TODO(brianderson): Remove this restriction to improve throughput or |
472 // make it conditional on impl_latency_takes_priority_. | 477 // make it conditional on ImplLatencyTakesPriority. |
473 bool just_swapped_in_deadline = | 478 bool just_swapped_in_deadline = |
474 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && | 479 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && |
475 did_perform_swap_in_last_draw_; | 480 did_perform_swap_in_last_draw_; |
476 if (SwapThrottled() && !just_swapped_in_deadline) | 481 if (SwapThrottled() && !just_swapped_in_deadline) |
477 return false; | 482 return false; |
478 } | 483 } |
479 | 484 |
480 if (skip_next_begin_main_frame_to_reduce_latency_) | 485 if (skip_next_begin_main_frame_to_reduce_latency_) |
481 return false; | 486 return false; |
482 | 487 |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
893 | 898 |
894 // This is used to prioritize impl-thread draws when the main thread isn't | 899 // 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 | 900 // 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 | 901 // don't have a pending tree -- otherwise we should give it a chance to |
897 // activate. | 902 // activate. |
898 // TODO(skyostil): Revisit this when we have more accurate deadline estimates. | 903 // TODO(skyostil): Revisit this when we have more accurate deadline estimates. |
899 if (begin_main_frame_state_ == BEGIN_MAIN_FRAME_STATE_IDLE && | 904 if (begin_main_frame_state_ == BEGIN_MAIN_FRAME_STATE_IDLE && |
900 !has_pending_tree_) | 905 !has_pending_tree_) |
901 return true; | 906 return true; |
902 | 907 |
903 // Prioritize impl-thread draws in impl_latency_takes_priority_ mode. | 908 // Prioritize impl-thread draws in ImplLatencyTakesPriority mode. |
904 if (impl_latency_takes_priority_) | 909 if (ImplLatencyTakesPriority()) |
905 return true; | 910 return true; |
906 | 911 |
907 return false; | 912 return false; |
908 } | 913 } |
909 | 914 |
910 bool SchedulerStateMachine::main_thread_missed_last_deadline() const { | 915 bool SchedulerStateMachine::main_thread_missed_last_deadline() const { |
911 return main_thread_missed_last_deadline_; | 916 return main_thread_missed_last_deadline_; |
912 } | 917 } |
913 | 918 |
914 bool SchedulerStateMachine::SwapThrottled() const { | 919 bool SchedulerStateMachine::SwapThrottled() const { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
971 | 976 |
972 did_perform_swap_in_last_draw_ = true; | 977 did_perform_swap_in_last_draw_ = true; |
973 last_frame_number_swap_performed_ = current_frame_number_; | 978 last_frame_number_swap_performed_ = current_frame_number_; |
974 } | 979 } |
975 | 980 |
976 void SchedulerStateMachine::DidSwapBuffersComplete() { | 981 void SchedulerStateMachine::DidSwapBuffersComplete() { |
977 TRACE_EVENT_ASYNC_END0("cc", "Scheduler:pending_swaps", this); | 982 TRACE_EVENT_ASYNC_END0("cc", "Scheduler:pending_swaps", this); |
978 pending_swaps_--; | 983 pending_swaps_--; |
979 } | 984 } |
980 | 985 |
981 void SchedulerStateMachine::SetImplLatencyTakesPriority( | 986 void SchedulerStateMachine::SetSmoothnessMode( |
982 bool impl_latency_takes_priority) { | 987 bool smoothness_takes_priority, |
983 impl_latency_takes_priority_ = impl_latency_takes_priority; | 988 bool scroll_affects_scroll_handler) { |
| 989 smoothness_takes_priority_ = smoothness_takes_priority; |
| 990 scroll_affects_scroll_handler_ = scroll_affects_scroll_handler; |
| 991 } |
| 992 |
| 993 void SchedulerStateMachine::SetCriticalBeginMainFrameToActivateIsFast( |
| 994 bool is_fast) { |
| 995 critical_begin_main_frame_to_activate_is_fast_ = is_fast; |
| 996 } |
| 997 |
| 998 bool SchedulerStateMachine::ImplLatencyTakesPriority() const { |
| 999 // Attempt to synchronize with the main thread if it has a scroll listener |
| 1000 // and is fast. |
| 1001 if (scroll_affects_scroll_handler_ && |
| 1002 critical_begin_main_frame_to_activate_is_fast_) |
| 1003 return false; |
| 1004 |
| 1005 // Don't wait for the main thread if we are prioritizing smoothness. |
| 1006 if (smoothness_takes_priority_) |
| 1007 return true; |
| 1008 |
| 1009 return false; |
984 } | 1010 } |
985 | 1011 |
986 void SchedulerStateMachine::DidDrawIfPossibleCompleted(DrawResult result) { | 1012 void SchedulerStateMachine::DidDrawIfPossibleCompleted(DrawResult result) { |
987 switch (result) { | 1013 switch (result) { |
988 case INVALID_RESULT: | 1014 case INVALID_RESULT: |
989 NOTREACHED() << "Uninitialized DrawResult."; | 1015 NOTREACHED() << "Uninitialized DrawResult."; |
990 break; | 1016 break; |
991 case DRAW_ABORTED_CANT_DRAW: | 1017 case DRAW_ABORTED_CANT_DRAW: |
992 case DRAW_ABORTED_CONTEXT_LOST: | 1018 case DRAW_ABORTED_CONTEXT_LOST: |
993 NOTREACHED() << "Invalid return value from DrawAndSwapIfPossible:" | 1019 NOTREACHED() << "Invalid return value from DrawAndSwapIfPossible:" |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1114 case OUTPUT_SURFACE_ACTIVE: | 1140 case OUTPUT_SURFACE_ACTIVE: |
1115 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: | 1141 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: |
1116 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: | 1142 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: |
1117 return true; | 1143 return true; |
1118 } | 1144 } |
1119 NOTREACHED(); | 1145 NOTREACHED(); |
1120 return false; | 1146 return false; |
1121 } | 1147 } |
1122 | 1148 |
1123 } // namespace cc | 1149 } // namespace cc |
OLD | NEW |