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

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: Add SchedulerStateMachine::SwapThrottled Created 5 years, 7 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 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 state->SetBoolean("active_tree_needs_first_draw", 230 state->SetBoolean("active_tree_needs_first_draw",
232 active_tree_needs_first_draw_); 231 active_tree_needs_first_draw_);
233 state->SetBoolean("wait_for_active_tree_ready_to_draw", 232 state->SetBoolean("wait_for_active_tree_ready_to_draw",
234 wait_for_active_tree_ready_to_draw_); 233 wait_for_active_tree_ready_to_draw_);
235 state->SetBoolean("did_create_and_initialize_first_output_surface", 234 state->SetBoolean("did_create_and_initialize_first_output_surface",
236 did_create_and_initialize_first_output_surface_); 235 did_create_and_initialize_first_output_surface_);
237 state->SetBoolean("impl_latency_takes_priority", 236 state->SetBoolean("impl_latency_takes_priority",
238 impl_latency_takes_priority_); 237 impl_latency_takes_priority_);
239 state->SetBoolean("main_thread_is_in_high_latency_mode", 238 state->SetBoolean("main_thread_is_in_high_latency_mode",
240 MainThreadIsInHighLatencyMode()); 239 MainThreadIsInHighLatencyMode());
241 state->SetBoolean("skip_begin_main_frame_to_reduce_latency",
242 skip_begin_main_frame_to_reduce_latency_);
243 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", 240 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency",
244 skip_next_begin_main_frame_to_reduce_latency_); 241 skip_next_begin_main_frame_to_reduce_latency_);
245 state->SetBoolean("continuous_painting", continuous_painting_); 242 state->SetBoolean("continuous_painting", continuous_painting_);
246 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_); 243 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_);
247 state->SetBoolean("video_needs_begin_frames", video_needs_begin_frames_); 244 state->SetBoolean("video_needs_begin_frames", video_needs_begin_frames_);
248 state->SetBoolean("defer_commits", defer_commits_); 245 state->SetBoolean("defer_commits", defer_commits_);
249 state->SetBoolean("last_commit_had_no_updates", last_commit_had_no_updates_); 246 state->SetBoolean("last_commit_had_no_updates", last_commit_had_no_updates_);
250 state->SetBoolean("did_request_swap_in_last_frame", 247 state->SetBoolean("did_request_swap_in_last_frame",
251 did_request_swap_in_last_frame_); 248 did_request_swap_in_last_frame_);
252 state->SetBoolean("did_perform_swap_in_last_draw", 249 state->SetBoolean("did_perform_swap_in_last_draw",
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 // this before checking for aborted draws because aborted draws do not request 327 // this before checking for aborted draws because aborted draws do not request
331 // a swap. 328 // a swap.
332 if (request_swap_funnel_) 329 if (request_swap_funnel_)
333 return false; 330 return false;
334 331
335 // Don't draw if we are waiting on the first commit after a surface. 332 // Don't draw if we are waiting on the first commit after a surface.
336 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE) 333 if (output_surface_state_ != OUTPUT_SURFACE_ACTIVE)
337 return false; 334 return false;
338 335
339 // Do not queue too many swaps. 336 // Do not queue too many swaps.
340 if (pending_swaps_ >= max_pending_swaps_) 337 if (SwapThrottled())
341 return false; 338 return false;
342 339
343 // Except for the cases above, do not draw outside of the BeginImplFrame 340 // Except for the cases above, do not draw outside of the BeginImplFrame
344 // deadline. 341 // deadline.
345 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) 342 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
346 return false; 343 return false;
347 344
348 // Only handle forced redraws due to timeouts on the regular deadline. 345 // Only handle forced redraws due to timeouts on the regular deadline.
349 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 346 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
350 return true; 347 return true;
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 401
405 bool SchedulerStateMachine::SendingBeginMainFrameMightCauseDeadlock() const { 402 bool SchedulerStateMachine::SendingBeginMainFrameMightCauseDeadlock() const {
406 // NPAPI is the only case where the UI thread makes synchronous calls to the 403 // NPAPI is the only case where the UI thread makes synchronous calls to the
407 // Renderer main thread. During that synchronous call, we may not get a 404 // Renderer main thread. During that synchronous call, we may not get a
408 // SwapAck for the UI thread, which may prevent BeginMainFrame's from 405 // SwapAck for the UI thread, which may prevent BeginMainFrame's from
409 // completing if there's enough back pressure. If the BeginMainFrame can't 406 // completing if there's enough back pressure. If the BeginMainFrame can't
410 // make progress, the Renderer can't service the UI thread's synchronous call 407 // make progress, the Renderer can't service the UI thread's synchronous call
411 // and we have deadlock. 408 // and we have deadlock.
412 // This returns true if there's too much backpressure to finish a commit 409 // This returns true if there's too much backpressure to finish a commit
413 // if we were to initiate a BeginMainFrame. 410 // if we were to initiate a BeginMainFrame.
414 return has_pending_tree_ && active_tree_needs_first_draw_ && 411 return has_pending_tree_ && active_tree_needs_first_draw_ && SwapThrottled();
415 pending_swaps_ >= max_pending_swaps_;
416 } 412 }
417 413
418 bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { 414 bool SchedulerStateMachine::ShouldSendBeginMainFrame() const {
419 if (!CouldSendBeginMainFrame()) 415 if (!CouldSendBeginMainFrame())
420 return false; 416 return false;
421 417
422 // Do not send begin main frame too many times in a single frame. 418 // Do not send begin main frame too many times in a single frame.
423 if (send_begin_main_frame_funnel_) 419 if (send_begin_main_frame_funnel_)
424 return false; 420 return false;
425 421
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 return false; 459 return false;
464 460
465 if (!settings_.main_frame_while_swap_throttled_enabled) { 461 if (!settings_.main_frame_while_swap_throttled_enabled) {
466 // SwapAck throttle the BeginMainFrames unless we just swapped to 462 // SwapAck throttle the BeginMainFrames unless we just swapped to
467 // potentially improve impl-thread latency over main-thread throughput. 463 // potentially improve impl-thread latency over main-thread throughput.
468 // TODO(brianderson): Remove this restriction to improve throughput or 464 // TODO(brianderson): Remove this restriction to improve throughput or
469 // make it conditional on impl_latency_takes_priority_. 465 // make it conditional on impl_latency_takes_priority_.
470 bool just_swapped_in_deadline = 466 bool just_swapped_in_deadline =
471 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && 467 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE &&
472 did_perform_swap_in_last_draw_; 468 did_perform_swap_in_last_draw_;
473 if (pending_swaps_ >= max_pending_swaps_ && !just_swapped_in_deadline) 469 if (SwapThrottled() && !just_swapped_in_deadline)
474 return false; 470 return false;
475 } 471 }
476 472
477 if (skip_begin_main_frame_to_reduce_latency_) 473 if (skip_next_begin_main_frame_to_reduce_latency_)
478 return false; 474 return false;
479 475
480 return true; 476 return true;
481 } 477 }
482 478
483 bool SchedulerStateMachine::ShouldCommit() const { 479 bool SchedulerStateMachine::ShouldCommit() const {
484 if (commit_state_ != COMMIT_STATE_READY_TO_COMMIT) 480 if (commit_state_ != COMMIT_STATE_READY_TO_COMMIT)
485 return false; 481 return false;
486 482
487 // We must not finish the commit until the pending tree is free. 483 // We must not finish the commit until the pending tree is free.
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 did_request_swap_in_last_frame_ = false; 852 did_request_swap_in_last_frame_ = false;
857 853
858 // Clear funnels for any actions we perform during the frame. 854 // Clear funnels for any actions we perform during the frame.
859 animate_funnel_ = false; 855 animate_funnel_ = false;
860 send_begin_main_frame_funnel_ = false; 856 send_begin_main_frame_funnel_ = false;
861 invalidate_output_surface_funnel_ = false; 857 invalidate_output_surface_funnel_ = false;
862 858
863 // "Drain" the PrepareTiles funnel. 859 // "Drain" the PrepareTiles funnel.
864 if (prepare_tiles_funnel_ > 0) 860 if (prepare_tiles_funnel_ > 0)
865 prepare_tiles_funnel_--; 861 prepare_tiles_funnel_--;
866
867 skip_begin_main_frame_to_reduce_latency_ =
868 skip_next_begin_main_frame_to_reduce_latency_;
869 skip_next_begin_main_frame_to_reduce_latency_ = false;
870 } 862 }
871 863
872 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() { 864 void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() {
873 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME; 865 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME;
874 } 866 }
875 867
876 void SchedulerStateMachine::OnBeginImplFrameDeadline() { 868 void SchedulerStateMachine::OnBeginImplFrameDeadline() {
877 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; 869 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE;
878 870
879 did_perform_swap_in_last_draw_ = false; 871 did_perform_swap_in_last_draw_ = false;
880 872
881 // Clear funnels for any actions we perform during the deadline. 873 // Clear funnels for any actions we perform during the deadline.
882 request_swap_funnel_ = false; 874 request_swap_funnel_ = false;
883 } 875 }
884 876
885 void SchedulerStateMachine::OnBeginImplFrameIdle() { 877 void SchedulerStateMachine::OnBeginImplFrameIdle() {
886 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_IDLE; 878 begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_IDLE;
879
880 skip_next_begin_main_frame_to_reduce_latency_ = false;
887 } 881 }
888 882
889 SchedulerStateMachine::BeginImplFrameDeadlineMode 883 SchedulerStateMachine::BeginImplFrameDeadlineMode
890 SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const { 884 SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const {
891 if (settings_.using_synchronous_renderer_compositor) { 885 if (settings_.using_synchronous_renderer_compositor) {
892 // No deadline for synchronous compositor. 886 // No deadline for synchronous compositor.
893 return BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE; 887 return BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE;
894 } else if (wait_for_active_tree_ready_to_draw_) { 888 } else if (wait_for_active_tree_ready_to_draw_) {
895 // When we are waiting for ready to draw signal, we do not wait to post a 889 // When we are waiting for ready to draw signal, we do not wait to post a
896 // deadline yet. 890 // deadline yet.
897 return BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW; 891 return BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW;
898 } else if (ShouldTriggerBeginImplFrameDeadlineImmediately()) { 892 } else if (ShouldTriggerBeginImplFrameDeadlineImmediately()) {
899 return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE; 893 return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE;
900 } else if (needs_redraw_ && pending_swaps_ < max_pending_swaps_) { 894 } else if (needs_redraw_ && !SwapThrottled()) {
901 // We have an animation or fast input path on the impl thread that wants 895 // We have an animation or fast input path on the impl thread that wants
902 // to draw, so don't wait too long for a new active tree. 896 // to draw, so don't wait too long for a new active tree.
903 // If we are swap throttled we should wait until we are unblocked. 897 // If we are swap throttled we should wait until we are unblocked.
904 return BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR; 898 return BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR;
905 } else { 899 } else {
906 // The impl thread doesn't have anything it wants to draw and we are just 900 // The impl thread doesn't have anything it wants to draw and we are just
907 // waiting for a new active tree or we are swap throttled. In short we are 901 // waiting for a new active tree or we are swap throttled. In short we are
908 // blocked. 902 // blocked.
909 return BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE; 903 return BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE;
910 } 904 }
911 } 905 }
912 906
913 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately() 907 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately()
914 const { 908 const {
915 // TODO(brianderson): This should take into account multiple commit sources.
916 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) 909 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)
917 return false; 910 return false;
918 911
919 // If we just forced activation, we should end the deadline right now. 912 // If we just forced activation, we should end the deadline right now.
920 if (PendingActivationsShouldBeForced() && !has_pending_tree_) 913 if (PendingActivationsShouldBeForced() && !has_pending_tree_)
921 return true; 914 return true;
922 915
923 // SwapAck throttle the deadline since we wont draw and swap anyway. 916 // SwapAck throttle the deadline since we wont draw and swap anyway.
924 if (pending_swaps_ >= max_pending_swaps_) 917 if (SwapThrottled())
925 return false; 918 return false;
926 919
927 if (active_tree_needs_first_draw_) 920 if (active_tree_needs_first_draw_)
928 return true; 921 return true;
929 922
930 if (!needs_redraw_) 923 if (!needs_redraw_)
931 return false; 924 return false;
932 925
933 // This is used to prioritize impl-thread draws when the main thread isn't 926 // This is used to prioritize impl-thread draws when the main thread isn't
934 // producing anything, e.g., after an aborted commit. We also check that we 927 // producing anything, e.g., after an aborted commit. We also check that we
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 static_cast<int>(begin_impl_frame_state_), 1161 static_cast<int>(begin_impl_frame_state_),
1169 static_cast<int>(commit_state_), 1162 static_cast<int>(commit_state_),
1170 has_pending_tree_ ? 'T' : 'F', 1163 has_pending_tree_ ? 'T' : 'F',
1171 pending_tree_is_ready_for_activation_ ? 'T' : 'F', 1164 pending_tree_is_ready_for_activation_ ? 'T' : 'F',
1172 active_tree_needs_first_draw_ ? 'T' : 'F', 1165 active_tree_needs_first_draw_ ? 'T' : 'F',
1173 max_pending_swaps_, 1166 max_pending_swaps_,
1174 pending_swaps_); 1167 pending_swaps_);
1175 } 1168 }
1176 1169
1177 } // namespace cc 1170 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698