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

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

Issue 1133673004: cc: Heuristic for Renderer latency recovery (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Better names and durations Created 5 years, 5 months 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 30 matching lines...) Expand all
41 needs_commit_(false), 41 needs_commit_(false),
42 visible_(false), 42 visible_(false),
43 can_start_(false), 43 can_start_(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 impl_latency_takes_priority_(false),
50 skip_next_begin_main_frame_to_reduce_latency_(false), 50 skip_next_begin_main_frame_to_reduce_latency_(false),
51 skip_begin_main_frame_to_reduce_latency_(false),
52 continuous_painting_(false), 51 continuous_painting_(false),
53 children_need_begin_frames_(false), 52 children_need_begin_frames_(false),
54 defer_commits_(false), 53 defer_commits_(false),
55 video_needs_begin_frames_(false), 54 video_needs_begin_frames_(false),
56 last_commit_had_no_updates_(false), 55 last_commit_had_no_updates_(false),
57 wait_for_active_tree_ready_to_draw_(false), 56 wait_for_active_tree_ready_to_draw_(false),
58 did_request_swap_in_last_frame_(false), 57 did_request_swap_in_last_frame_(false),
59 did_perform_swap_in_last_draw_(false) { 58 did_perform_swap_in_last_draw_(false) {
60 } 59 }
61 60
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 state->SetBoolean("active_tree_needs_first_draw", 232 state->SetBoolean("active_tree_needs_first_draw",
234 active_tree_needs_first_draw_); 233 active_tree_needs_first_draw_);
235 state->SetBoolean("wait_for_active_tree_ready_to_draw", 234 state->SetBoolean("wait_for_active_tree_ready_to_draw",
236 wait_for_active_tree_ready_to_draw_); 235 wait_for_active_tree_ready_to_draw_);
237 state->SetBoolean("did_create_and_initialize_first_output_surface", 236 state->SetBoolean("did_create_and_initialize_first_output_surface",
238 did_create_and_initialize_first_output_surface_); 237 did_create_and_initialize_first_output_surface_);
239 state->SetBoolean("impl_latency_takes_priority", 238 state->SetBoolean("impl_latency_takes_priority",
240 impl_latency_takes_priority_); 239 impl_latency_takes_priority_);
241 state->SetBoolean("main_thread_is_in_high_latency_mode", 240 state->SetBoolean("main_thread_is_in_high_latency_mode",
242 MainThreadIsInHighLatencyMode()); 241 MainThreadIsInHighLatencyMode());
243 state->SetBoolean("skip_begin_main_frame_to_reduce_latency",
244 skip_begin_main_frame_to_reduce_latency_);
245 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", 242 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency",
246 skip_next_begin_main_frame_to_reduce_latency_); 243 skip_next_begin_main_frame_to_reduce_latency_);
247 state->SetBoolean("continuous_painting", continuous_painting_); 244 state->SetBoolean("continuous_painting", continuous_painting_);
248 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_); 245 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_);
249 state->SetBoolean("video_needs_begin_frames", video_needs_begin_frames_); 246 state->SetBoolean("video_needs_begin_frames", video_needs_begin_frames_);
250 state->SetBoolean("defer_commits", defer_commits_); 247 state->SetBoolean("defer_commits", defer_commits_);
251 state->SetBoolean("last_commit_had_no_updates", last_commit_had_no_updates_); 248 state->SetBoolean("last_commit_had_no_updates", last_commit_had_no_updates_);
252 state->SetBoolean("did_request_swap_in_last_frame", 249 state->SetBoolean("did_request_swap_in_last_frame",
253 did_request_swap_in_last_frame_); 250 did_request_swap_in_last_frame_);
254 state->SetBoolean("did_perform_swap_in_last_draw", 251 state->SetBoolean("did_perform_swap_in_last_draw",
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 // this before checking for aborted draws because aborted draws do not request 329 // this before checking for aborted draws because aborted draws do not request
333 // a swap. 330 // a swap.
334 if (request_swap_funnel_) 331 if (request_swap_funnel_)
335 return false; 332 return false;
336 333
337 // Don't draw if we are waiting on the first commit after a surface. 334 // Don't draw if we are waiting on the first commit after a surface.
338 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE) 335 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE)
339 return false; 336 return false;
340 337
341 // Do not queue too many swaps. 338 // Do not queue too many swaps.
342 if (pending_swaps_ >= max_pending_swaps_) 339 if (SwapThrottled())
343 return false; 340 return false;
344 341
345 // Except for the cases above, do not draw outside of the BeginImplFrame 342 // Except for the cases above, do not draw outside of the BeginImplFrame
346 // deadline. 343 // deadline.
347 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) 344 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
348 return false; 345 return false;
349 346
350 // Only handle forced redraws due to timeouts on the regular deadline. 347 // Only handle forced redraws due to timeouts on the regular deadline.
351 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 348 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
352 return true; 349 return true;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 403
407 bool SchedulerStateMachine::SendingBeginMainFrameMightCauseDeadlock() const { 404 bool SchedulerStateMachine::SendingBeginMainFrameMightCauseDeadlock() const {
408 // NPAPI is the only case where the UI thread makes synchronous calls to the 405 // NPAPI is the only case where the UI thread makes synchronous calls to the
409 // Renderer main thread. During that synchronous call, we may not get a 406 // Renderer main thread. During that synchronous call, we may not get a
410 // SwapAck for the UI thread, which may prevent BeginMainFrame's from 407 // SwapAck for the UI thread, which may prevent BeginMainFrame's from
411 // completing if there's enough back pressure. If the BeginMainFrame can't 408 // completing if there's enough back pressure. If the BeginMainFrame can't
412 // make progress, the Renderer can't service the UI thread's synchronous call 409 // make progress, the Renderer can't service the UI thread's synchronous call
413 // and we have deadlock. 410 // and we have deadlock.
414 // This returns true if there's too much backpressure to finish a commit 411 // This returns true if there's too much backpressure to finish a commit
415 // if we were to initiate a BeginMainFrame. 412 // if we were to initiate a BeginMainFrame.
416 return has_pending_tree_ && active_tree_needs_first_draw_ && 413 return has_pending_tree_ && active_tree_needs_first_draw_ && SwapThrottled();
417 pending_swaps_ >= max_pending_swaps_;
418 } 414 }
419 415
420 bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { 416 bool SchedulerStateMachine::ShouldSendBeginMainFrame() const {
421 if (!CouldSendBeginMainFrame()) 417 if (!CouldSendBeginMainFrame())
422 return false; 418 return false;
423 419
424 // Do not send begin main frame too many times in a single frame. 420 // Do not send begin main frame too many times in a single frame.
425 if (send_begin_main_frame_funnel_) 421 if (send_begin_main_frame_funnel_)
426 return false; 422 return false;
427 423
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 return false; 461 return false;
466 462
467 if (!settings_.main_frame_while_swap_throttled_enabled) { 463 if (!settings_.main_frame_while_swap_throttled_enabled) {
468 // SwapAck throttle the BeginMainFrames unless we just swapped to 464 // SwapAck throttle the BeginMainFrames unless we just swapped to
469 // potentially improve impl-thread latency over main-thread throughput. 465 // potentially improve impl-thread latency over main-thread throughput.
470 // TODO(brianderson): Remove this restriction to improve throughput or 466 // TODO(brianderson): Remove this restriction to improve throughput or
471 // make it conditional on impl_latency_takes_priority_. 467 // make it conditional on impl_latency_takes_priority_.
472 bool just_swapped_in_deadline = 468 bool just_swapped_in_deadline =
473 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && 469 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE &&
474 did_perform_swap_in_last_draw_; 470 did_perform_swap_in_last_draw_;
475 if (pending_swaps_ >= max_pending_swaps_ && !just_swapped_in_deadline) 471 if (SwapThrottled() && !just_swapped_in_deadline)
476 return false; 472 return false;
477 } 473 }
478 474
479 if (skip_begin_main_frame_to_reduce_latency_) 475 if (skip_next_begin_main_frame_to_reduce_latency_)
480 return false; 476 return false;
481 477
482 return true; 478 return true;
483 } 479 }
484 480
485 bool SchedulerStateMachine::ShouldCommit() const { 481 bool SchedulerStateMachine::ShouldCommit() const {
486 if (commit_state_ != COMMIT_STATE_READY_TO_COMMIT) 482 if (commit_state_ != COMMIT_STATE_READY_TO_COMMIT)
487 return false; 483 return false;
488 484
489 // We must not finish the commit until the pending tree is free. 485 // We must not finish the commit until the pending tree is free.
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after
851 did_request_swap_in_last_frame_ = false; 847 did_request_swap_in_last_frame_ = false;
852 848
853 // Clear funnels for any actions we perform during the frame. 849 // Clear funnels for any actions we perform during the frame.
854 animate_funnel_ = false; 850 animate_funnel_ = false;
855 send_begin_main_frame_funnel_ = false; 851 send_begin_main_frame_funnel_ = false;
856 invalidate_output_surface_funnel_ = false; 852 invalidate_output_surface_funnel_ = false;
857 853
858 // "Drain" the PrepareTiles funnel. 854 // "Drain" the PrepareTiles funnel.
859 if (prepare_tiles_funnel_ > 0) 855 if (prepare_tiles_funnel_ > 0)
860 prepare_tiles_funnel_--; 856 prepare_tiles_funnel_--;
861
862 skip_begin_main_frame_to_reduce_latency_ =
863 skip_next_begin_main_frame_to_reduce_latency_;
864 skip_next_begin_main_frame_to_reduce_latency_ = false;
865 } 857 }
866 858
867 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() { 859 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() {
868 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME; 860 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME;
869 } 861 }
870 862
871 void SchedulerStateMachine::OnBeginImplFrameDeadline() { 863 void SchedulerStateMachine::OnBeginImplFrameDeadline() {
872 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; 864 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE;
873 865
874 did_perform_swap_in_last_draw_ = false; 866 did_perform_swap_in_last_draw_ = false;
875 867
876 // Clear funnels for any actions we perform during the deadline. 868 // Clear funnels for any actions we perform during the deadline.
877 request_swap_funnel_ = false; 869 request_swap_funnel_ = false;
878 870
879 // Allow one PrepareTiles per draw for synchronous compositor. 871 // Allow one PrepareTiles per draw for synchronous compositor.
880 if (settings_.using_synchronous_renderer_compositor) { 872 if (settings_.using_synchronous_renderer_compositor) {
881 if (prepare_tiles_funnel_ > 0) 873 if (prepare_tiles_funnel_ > 0)
882 prepare_tiles_funnel_--; 874 prepare_tiles_funnel_--;
883 } 875 }
884 } 876 }
885 877
886 void SchedulerStateMachine::OnBeginImplFrameIdle() { 878 void SchedulerStateMachine::OnBeginImplFrameIdle() {
887 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_IDLE; 879 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_IDLE;
880
881 skip_next_begin_main_frame_to_reduce_latency_ = false;
sunnyps 2015/07/08 22:37:12 Why was this moved here?
brianderson 2015/07/09 01:28:11 Resetting it here allowed me to get rid of the ski
888 } 882 }
889 883
890 SchedulerStateMachine::BeginImplFrameDeadlineMode 884 SchedulerStateMachine::BeginImplFrameDeadlineMode
891 SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const { 885 SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const {
892 if (settings_.using_synchronous_renderer_compositor) { 886 if (settings_.using_synchronous_renderer_compositor) {
893 // No deadline for synchronous compositor. 887 // No deadline for synchronous compositor.
894 return BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE; 888 return BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE;
895 } else if (wait_for_active_tree_ready_to_draw_) { 889 } else if (wait_for_active_tree_ready_to_draw_) {
896 // When we are waiting for ready to draw signal, we do not wait to post a 890 // When we are waiting for ready to draw signal, we do not wait to post a
897 // deadline yet. 891 // deadline yet.
898 return BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW; 892 return BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW;
899 } else if (ShouldTriggerBeginImplFrameDeadlineImmediately()) { 893 } else if (ShouldTriggerBeginImplFrameDeadlineImmediately()) {
900 return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE; 894 return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE;
901 } else if (needs_redraw_ && pending_swaps_ < max_pending_swaps_) { 895 } else if (needs_redraw_ && !SwapThrottled()) {
902 // We have an animation or fast input path on the impl thread that wants 896 // We have an animation or fast input path on the impl thread that wants
903 // to draw, so don't wait too long for a new active tree. 897 // to draw, so don't wait too long for a new active tree.
904 // If we are swap throttled we should wait until we are unblocked. 898 // If we are swap throttled we should wait until we are unblocked.
905 return BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR; 899 return BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR;
906 } else { 900 } else {
907 // The impl thread doesn't have anything it wants to draw and we are just 901 // The impl thread doesn't have anything it wants to draw and we are just
908 // waiting for a new active tree or we are swap throttled. In short we are 902 // waiting for a new active tree or we are swap throttled. In short we are
909 // blocked. 903 // blocked.
910 return BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE; 904 return BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE;
911 } 905 }
912 } 906 }
913 907
914 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately() 908 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately()
915 const { 909 const {
916 // TODO(brianderson): This should take into account multiple commit sources.
917 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) 910 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)
918 return false; 911 return false;
919 912
920 // If we just forced activation, we should end the deadline right now. 913 // If we just forced activation, we should end the deadline right now.
921 if (PendingActivationsShouldBeForced() && !has_pending_tree_) 914 if (PendingActivationsShouldBeForced() && !has_pending_tree_)
922 return true; 915 return true;
923 916
924 // SwapAck throttle the deadline since we wont draw and swap anyway. 917 // SwapAck throttle the deadline since we wont draw and swap anyway.
925 if (pending_swaps_ >= max_pending_swaps_) 918 if (SwapThrottled())
926 return false; 919 return false;
927 920
928 if (active_tree_needs_first_draw_) 921 if (active_tree_needs_first_draw_)
929 return true; 922 return true;
930 923
931 if (!needs_redraw_) 924 if (!needs_redraw_)
932 return false; 925 return false;
933 926
934 // This is used to prioritize impl-thread draws when the main thread isn't 927 // This is used to prioritize impl-thread draws when the main thread isn't
935 // producing anything, e.g., after an aborted commit. We also check that we 928 // producing anything, e.g., after an aborted commit. We also check that we
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
1157 case OUTPUT_SURFACE_ACTIVE: 1150 case OUTPUT_SURFACE_ACTIVE:
1158 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: 1151 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT:
1159 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: 1152 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION:
1160 return true; 1153 return true;
1161 } 1154 }
1162 NOTREACHED(); 1155 NOTREACHED();
1163 return false; 1156 return false;
1164 } 1157 }
1165 1158
1166 } // namespace cc 1159 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698