Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(375)

Side by Side Diff: cc/scheduler/scheduler_state_machine.cc

Issue 1425973003: cc: Don't attempt main thread synchronization if it is slow. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 28 matching lines...) Expand all
39 needs_animate_(false), 39 needs_animate_(false),
40 needs_prepare_tiles_(false), 40 needs_prepare_tiles_(false),
41 needs_begin_main_frame_(false), 41 needs_begin_main_frame_(false),
42 visible_(false), 42 visible_(false),
43 resourceless_draw_(false), 43 resourceless_draw_(false),
44 can_draw_(false), 44 can_draw_(false),
45 has_pending_tree_(false), 45 has_pending_tree_(false),
46 pending_tree_is_ready_for_activation_(false), 46 pending_tree_is_ready_for_activation_(false),
47 active_tree_needs_first_draw_(false), 47 active_tree_needs_first_draw_(false),
48 did_create_and_initialize_first_output_surface_(false), 48 did_create_and_initialize_first_output_surface_(false),
49 impl_latency_takes_priority_(false), 49 smoothness_takes_priority_(false),
50 scroll_affects_scroll_handler_(false),
51 main_thread_is_fast_(true),
50 main_thread_missed_last_deadline_(false), 52 main_thread_missed_last_deadline_(false),
51 skip_next_begin_main_frame_to_reduce_latency_(false), 53 skip_next_begin_main_frame_to_reduce_latency_(false),
52 children_need_begin_frames_(false), 54 children_need_begin_frames_(false),
53 defer_commits_(false), 55 defer_commits_(false),
54 video_needs_begin_frames_(false), 56 video_needs_begin_frames_(false),
55 last_commit_had_no_updates_(false), 57 last_commit_had_no_updates_(false),
56 wait_for_ready_to_draw_(false), 58 wait_for_ready_to_draw_(false),
57 did_request_swap_in_last_frame_(false), 59 did_request_swap_in_last_frame_(false),
58 did_perform_swap_in_last_draw_(false) {} 60 did_perform_swap_in_last_draw_(false) {}
59 61
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 state->SetBoolean("can_draw", can_draw_); 230 state->SetBoolean("can_draw", can_draw_);
229 state->SetBoolean("resourceless_draw", resourceless_draw_); 231 state->SetBoolean("resourceless_draw", resourceless_draw_);
230 state->SetBoolean("has_pending_tree", has_pending_tree_); 232 state->SetBoolean("has_pending_tree", has_pending_tree_);
231 state->SetBoolean("pending_tree_is_ready_for_activation", 233 state->SetBoolean("pending_tree_is_ready_for_activation",
232 pending_tree_is_ready_for_activation_); 234 pending_tree_is_ready_for_activation_);
233 state->SetBoolean("active_tree_needs_first_draw", 235 state->SetBoolean("active_tree_needs_first_draw",
234 active_tree_needs_first_draw_); 236 active_tree_needs_first_draw_);
235 state->SetBoolean("wait_for_ready_to_draw", wait_for_ready_to_draw_); 237 state->SetBoolean("wait_for_ready_to_draw", wait_for_ready_to_draw_);
236 state->SetBoolean("did_create_and_initialize_first_output_surface", 238 state->SetBoolean("did_create_and_initialize_first_output_surface",
237 did_create_and_initialize_first_output_surface_); 239 did_create_and_initialize_first_output_surface_);
238 state->SetBoolean("impl_latency_takes_priority", 240 state->SetBoolean("smoothness_takes_priority", smoothness_takes_priority_);
239 impl_latency_takes_priority_); 241 state->SetBoolean("scroll_affects_scroll_handler",
242 scroll_affects_scroll_handler_);
243 state->SetBoolean("main_thread_is_fast", main_thread_is_fast_);
240 state->SetBoolean("main_thread_missed_last_deadline", 244 state->SetBoolean("main_thread_missed_last_deadline",
241 main_thread_missed_last_deadline_); 245 main_thread_missed_last_deadline_);
242 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", 246 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency",
243 skip_next_begin_main_frame_to_reduce_latency_); 247 skip_next_begin_main_frame_to_reduce_latency_);
244 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_); 248 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_);
245 state->SetBoolean("video_needs_begin_frames", video_needs_begin_frames_); 249 state->SetBoolean("video_needs_begin_frames", video_needs_begin_frames_);
246 state->SetBoolean("defer_commits", defer_commits_); 250 state->SetBoolean("defer_commits", defer_commits_);
247 state->SetBoolean("last_commit_had_no_updates", last_commit_had_no_updates_); 251 state->SetBoolean("last_commit_had_no_updates", last_commit_had_no_updates_);
248 state->SetBoolean("did_request_swap_in_last_frame", 252 state->SetBoolean("did_request_swap_in_last_frame",
249 did_request_swap_in_last_frame_); 253 did_request_swap_in_last_frame_);
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 return false; 427 return false;
424 428
425 // Only send BeginMainFrame when there isn't another commit pending already. 429 // Only send BeginMainFrame when there isn't another commit pending already.
426 // Other parts of the state machine indirectly defer the BeginMainFrame 430 // Other parts of the state machine indirectly defer the BeginMainFrame
427 // by transitioning to WAITING commit states rather than going 431 // by transitioning to WAITING commit states rather than going
428 // immediately to IDLE. 432 // immediately to IDLE.
429 if (begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_IDLE) 433 if (begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_IDLE)
430 return false; 434 return false;
431 435
432 // Don't send BeginMainFrame early if we are prioritizing the active tree 436 // Don't send BeginMainFrame early if we are prioritizing the active tree
433 // because of impl_latency_takes_priority_. 437 // because of ImplLatencyTakesPriority.
434 if (impl_latency_takes_priority_ && 438 if (ImplLatencyTakesPriority() &&
435 (has_pending_tree_ || active_tree_needs_first_draw_)) { 439 (has_pending_tree_ || active_tree_needs_first_draw_)) {
436 return false; 440 return false;
437 } 441 }
438 442
439 // We should not send BeginMainFrame while we are in the idle state since we 443 // We should not send BeginMainFrame while we are in the idle state since we
440 // might have new user input arriving soon. It's okay to send BeginMainFrame 444 // might have new user input arriving soon. It's okay to send BeginMainFrame
441 // for the synchronous compositor because the main thread is always high 445 // for the synchronous compositor because the main thread is always high
442 // latency in that case. 446 // latency in that case.
443 // TODO(brianderson): Allow sending BeginMainFrame while idle when the main 447 // TODO(brianderson): Allow sending BeginMainFrame while idle when the main
444 // thread isn't consuming user input for non-synchronous compositor. 448 // thread isn't consuming user input for non-synchronous compositor.
(...skipping 15 matching lines...) Expand all
460 return false; 464 return false;
461 465
462 // Make sure the BeginMainFrame can finish eventually if we start it. 466 // Make sure the BeginMainFrame can finish eventually if we start it.
463 if (SendingBeginMainFrameMightCauseDeadlock()) 467 if (SendingBeginMainFrameMightCauseDeadlock())
464 return false; 468 return false;
465 469
466 if (!settings_.main_frame_while_swap_throttled_enabled) { 470 if (!settings_.main_frame_while_swap_throttled_enabled) {
467 // SwapAck throttle the BeginMainFrames unless we just swapped to 471 // SwapAck throttle the BeginMainFrames unless we just swapped to
468 // potentially improve impl-thread latency over main-thread throughput. 472 // potentially improve impl-thread latency over main-thread throughput.
469 // TODO(brianderson): Remove this restriction to improve throughput or 473 // TODO(brianderson): Remove this restriction to improve throughput or
470 // make it conditional on impl_latency_takes_priority_. 474 // make it conditional on ImplLatencyTakesPriority.
471 bool just_swapped_in_deadline = 475 bool just_swapped_in_deadline =
472 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && 476 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE &&
473 did_perform_swap_in_last_draw_; 477 did_perform_swap_in_last_draw_;
474 if (SwapThrottled() && !just_swapped_in_deadline) 478 if (SwapThrottled() && !just_swapped_in_deadline)
475 return false; 479 return false;
476 } 480 }
477 481
478 if (skip_next_begin_main_frame_to_reduce_latency_) 482 if (skip_next_begin_main_frame_to_reduce_latency_)
479 return false; 483 return false;
480 484
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 897
894 // This is used to prioritize impl-thread draws when the main thread isn't 898 // 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 899 // 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 900 // don't have a pending tree -- otherwise we should give it a chance to
897 // activate. 901 // activate.
898 // TODO(skyostil): Revisit this when we have more accurate deadline estimates. 902 // TODO(skyostil): Revisit this when we have more accurate deadline estimates.
899 if (begin_main_frame_state_ == BEGIN_MAIN_FRAME_STATE_IDLE && 903 if (begin_main_frame_state_ == BEGIN_MAIN_FRAME_STATE_IDLE &&
900 !has_pending_tree_) 904 !has_pending_tree_)
901 return true; 905 return true;
902 906
903 // Prioritize impl-thread draws in impl_latency_takes_priority_ mode. 907 // Prioritize impl-thread draws in ImplLatencyTakesPriority mode.
904 if (impl_latency_takes_priority_) 908 if (ImplLatencyTakesPriority())
905 return true; 909 return true;
906 910
907 return false; 911 return false;
908 } 912 }
909 913
910 bool SchedulerStateMachine::main_thread_missed_last_deadline() const { 914 bool SchedulerStateMachine::main_thread_missed_last_deadline() const {
911 return main_thread_missed_last_deadline_; 915 return main_thread_missed_last_deadline_;
912 } 916 }
913 917
914 bool SchedulerStateMachine::SwapThrottled() const { 918 bool SchedulerStateMachine::SwapThrottled() const {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 DCHECK_LE(pending_swaps_, max_pending_swaps_); 972 DCHECK_LE(pending_swaps_, max_pending_swaps_);
969 973
970 did_perform_swap_in_last_draw_ = true; 974 did_perform_swap_in_last_draw_ = true;
971 last_frame_number_swap_performed_ = current_frame_number_; 975 last_frame_number_swap_performed_ = current_frame_number_;
972 } 976 }
973 977
974 void SchedulerStateMachine::DidSwapBuffersComplete() { 978 void SchedulerStateMachine::DidSwapBuffersComplete() {
975 pending_swaps_--; 979 pending_swaps_--;
976 } 980 }
977 981
978 void SchedulerStateMachine::SetImplLatencyTakesPriority( 982 void SchedulerStateMachine::SetSmoothnessMode(
979 bool impl_latency_takes_priority) { 983 bool smoothness_takes_priority,
980 impl_latency_takes_priority_ = impl_latency_takes_priority; 984 bool scroll_affects_scroll_handler) {
985 smoothness_takes_priority_ = smoothness_takes_priority;
986 scroll_affects_scroll_handler_ = scroll_affects_scroll_handler;
987 }
988
989 void SchedulerStateMachine::SetMainThreadIsFast(bool is_fast) {
990 main_thread_is_fast_ = is_fast;
991 }
992
993 bool SchedulerStateMachine::ImplLatencyTakesPriority() const {
994 // Attempt to synchronize with the main thread if it has a scroll listener
995 // and is fast.
996 if (scroll_affects_scroll_handler_ && main_thread_is_fast_)
brianderson 2015/10/29 17:56:51 Somewhat related to this patch, I wonder if we sho
Sami 2015/10/29 18:37:04 I think that describes the underlying thing pretty
997 return false;
998
999 // Don't wait for the main thread if we are prioritizing smoothness.
1000 if (smoothness_takes_priority_)
1001 return true;
1002
1003 return false;
981 } 1004 }
982 1005
983 void SchedulerStateMachine::DidDrawIfPossibleCompleted(DrawResult result) { 1006 void SchedulerStateMachine::DidDrawIfPossibleCompleted(DrawResult result) {
984 switch (result) { 1007 switch (result) {
985 case INVALID_RESULT: 1008 case INVALID_RESULT:
986 NOTREACHED() << "Uninitialized DrawResult."; 1009 NOTREACHED() << "Uninitialized DrawResult.";
987 break; 1010 break;
988 case DRAW_ABORTED_CANT_DRAW: 1011 case DRAW_ABORTED_CANT_DRAW:
989 case DRAW_ABORTED_CONTEXT_LOST: 1012 case DRAW_ABORTED_CONTEXT_LOST:
990 NOTREACHED() << "Invalid return value from DrawAndSwapIfPossible:" 1013 NOTREACHED() << "Invalid return value from DrawAndSwapIfPossible:"
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1107 case OUTPUT_SURFACE_ACTIVE: 1130 case OUTPUT_SURFACE_ACTIVE:
1108 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: 1131 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT:
1109 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: 1132 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION:
1110 return true; 1133 return true;
1111 } 1134 }
1112 NOTREACHED(); 1135 NOTREACHED();
1113 return false; 1136 return false;
1114 } 1137 }
1115 1138
1116 } // namespace cc 1139 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698