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

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

Issue 2411793008: Adds BeginFrameControl via DevTools.
Patch Set: BFC prototype v2 with allow_latency_opts and waiting for BFOs. Created 4 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
« no previous file with comments | « cc/scheduler/scheduler_state_machine.h ('k') | cc/surfaces/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 scroll_handler_state_( 53 scroll_handler_state_(
54 ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER), 54 ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER),
55 critical_begin_main_frame_to_activate_is_fast_(true), 55 critical_begin_main_frame_to_activate_is_fast_(true),
56 main_thread_missed_last_deadline_(false), 56 main_thread_missed_last_deadline_(false),
57 skip_next_begin_main_frame_to_reduce_latency_(false), 57 skip_next_begin_main_frame_to_reduce_latency_(false),
58 defer_commits_(false), 58 defer_commits_(false),
59 video_needs_begin_frames_(false), 59 video_needs_begin_frames_(false),
60 last_commit_had_no_updates_(false), 60 last_commit_had_no_updates_(false),
61 wait_for_ready_to_draw_(false), 61 wait_for_ready_to_draw_(false),
62 did_draw_in_last_frame_(false), 62 did_draw_in_last_frame_(false),
63 did_submit_in_last_frame_(false) {} 63 did_submit_in_last_frame_(false),
64 begin_frame_allows_latency_optimizations_(true) {}
64 65
65 const char* SchedulerStateMachine::CompositorFrameSinkStateToString( 66 const char* SchedulerStateMachine::CompositorFrameSinkStateToString(
66 CompositorFrameSinkState state) { 67 CompositorFrameSinkState state) {
67 switch (state) { 68 switch (state) {
68 case COMPOSITOR_FRAME_SINK_NONE: 69 case COMPOSITOR_FRAME_SINK_NONE:
69 return "COMPOSITOR_FRAME_SINK_NONE"; 70 return "COMPOSITOR_FRAME_SINK_NONE";
70 case COMPOSITOR_FRAME_SINK_ACTIVE: 71 case COMPOSITOR_FRAME_SINK_ACTIVE:
71 return "COMPOSITOR_FRAME_SINK_ACTIVE"; 72 return "COMPOSITOR_FRAME_SINK_ACTIVE";
72 case COMPOSITOR_FRAME_SINK_CREATING: 73 case COMPOSITOR_FRAME_SINK_CREATING:
73 return "COMPOSITOR_FRAME_SINK_CREATING"; 74 return "COMPOSITOR_FRAME_SINK_CREATING";
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 if (wait_for_ready_to_draw_) { 368 if (wait_for_ready_to_draw_) {
368 DCHECK(settings_.commit_to_active_tree); 369 DCHECK(settings_.commit_to_active_tree);
369 return false; 370 return false;
370 } 371 }
371 372
372 // Browser compositor commit steals any resources submitted in draw. Therefore 373 // Browser compositor commit steals any resources submitted in draw. Therefore
373 // drawing while a commit is pending is wasteful. 374 // drawing while a commit is pending is wasteful.
374 if (settings_.commit_to_active_tree && CommitPending()) 375 if (settings_.commit_to_active_tree && CommitPending())
375 return false; 376 return false;
376 377
377 // Only handle forced redraws due to timeouts on the regular deadline. 378 // Only handle forced redraws due to timeouts on the regular deadline and
378 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 379 // (temporarily) for |!begin_frame_allows_latency_optimizations_|.
380 if (ShouldForceDraw())
379 return true; 381 return true;
380 382
381 return needs_redraw_; 383 return needs_redraw_;
382 } 384 }
383 385
386 bool SchedulerStateMachine::ShouldForceDraw() const {
387 // Browser compositor doesn't support forced draws.
388 if (settings_.commit_to_active_tree)
389 return false;
390
391 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
392 return true;
393
394 // |!begin_frame_allows_latency_optimizations_| is typically used with long
395 // deadlines, for which we depend on a timely acknowledgment of the BeginFrame
396 // in the browser. Since we currently don't have a unified acknowledgment for
397 // unsuccessful draws, we force a draw and wait for surface damage in the
398 // browser's DisplayScheduler.
399 // TODO(eseckler): Remove once we have unified BeginFrame acknowledgments.
400 if (!begin_frame_allows_latency_optimizations_)
401 return true;
402
403 return false;
404 }
405
384 bool SchedulerStateMachine::ShouldActivatePendingTree() const { 406 bool SchedulerStateMachine::ShouldActivatePendingTree() const {
385 // There is nothing to activate. 407 // There is nothing to activate.
386 if (!has_pending_tree_) 408 if (!has_pending_tree_)
387 return false; 409 return false;
388 410
389 // We should not activate a second tree before drawing the first one. 411 // We should not activate a second tree before drawing the first one.
390 // Even if we need to force activation of the pending tree, we should abort 412 // Even if we need to force activation of the pending tree, we should abort
391 // drawing the active tree first. 413 // drawing the active tree first.
392 if (active_tree_needs_first_draw_) 414 if (active_tree_needs_first_draw_)
393 return false; 415 return false;
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 } 569 }
548 570
549 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { 571 SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
550 if (ShouldActivatePendingTree()) 572 if (ShouldActivatePendingTree())
551 return ACTION_ACTIVATE_SYNC_TREE; 573 return ACTION_ACTIVATE_SYNC_TREE;
552 if (ShouldCommit()) 574 if (ShouldCommit())
553 return ACTION_COMMIT; 575 return ACTION_COMMIT;
554 if (ShouldDraw()) { 576 if (ShouldDraw()) {
555 if (PendingDrawsShouldBeAborted()) 577 if (PendingDrawsShouldBeAborted())
556 return ACTION_DRAW_ABORT; 578 return ACTION_DRAW_ABORT;
557 else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 579 else if (ShouldForceDraw())
558 return ACTION_DRAW_FORCED; 580 return ACTION_DRAW_FORCED;
559 else 581 else
560 return ACTION_DRAW_IF_POSSIBLE; 582 return ACTION_DRAW_IF_POSSIBLE;
561 } 583 }
562 if (ShouldPrepareTiles()) 584 if (ShouldPrepareTiles())
563 return ACTION_PREPARE_TILES; 585 return ACTION_PREPARE_TILES;
564 if (ShouldSendBeginMainFrame()) 586 if (ShouldSendBeginMainFrame())
565 return ACTION_SEND_BEGIN_MAIN_FRAME; 587 return ACTION_SEND_BEGIN_MAIN_FRAME;
566 if (ShouldInvalidateCompositorFrameSink()) 588 if (ShouldInvalidateCompositorFrameSink())
567 return ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK; 589 return ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK;
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 782
761 void SchedulerStateMachine::SetVideoNeedsBeginFrames( 783 void SchedulerStateMachine::SetVideoNeedsBeginFrames(
762 bool video_needs_begin_frames) { 784 bool video_needs_begin_frames) {
763 video_needs_begin_frames_ = video_needs_begin_frames; 785 video_needs_begin_frames_ = video_needs_begin_frames;
764 } 786 }
765 787
766 void SchedulerStateMachine::SetDeferCommits(bool defer_commits) { 788 void SchedulerStateMachine::SetDeferCommits(bool defer_commits) {
767 defer_commits_ = defer_commits; 789 defer_commits_ = defer_commits;
768 } 790 }
769 791
792 void SchedulerStateMachine::SetBeginFrameAllowsLatencyOptimizations(
793 bool allow_latency_optimizations) {
794 // In this mode, we ensure that we don't skip the BeginFrame/BeginMainFrame
795 // and that we don't prioritize impl thread latency. Thus, we first give the
796 // main thread a chance to produce updates, and only if it doesn't (or doesn't
797 // respond in time for the deadline), we produce an impl frame.
798
799 // |!allow_latency_optimizations| is often used in combination with long or
800 // infinite BeginFrame deadlines. To respond timely, we rely on triggering the
801 // BeginFrame deadline immediately if the main frame has no updates or as soon
802 // as it was activated (see ShouldTriggerBeginImplFrameDeadlineImmediately()).
803
804 begin_frame_allows_latency_optimizations_ = allow_latency_optimizations;
805 }
806
770 // These are the cases where we require a BeginFrame message to make progress 807 // These are the cases where we require a BeginFrame message to make progress
771 // on requested actions. 808 // on requested actions.
772 bool SchedulerStateMachine::BeginFrameRequiredForAction() const { 809 bool SchedulerStateMachine::BeginFrameRequiredForAction() const {
773 // The forced draw respects our normal draw scheduling, so we need to 810 // The forced draw respects our normal draw scheduling, so we need to
774 // request a BeginImplFrame for it. 811 // request a BeginImplFrame for it.
775 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) 812 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
776 return true; 813 return true;
777 814
778 return needs_redraw_ || needs_one_begin_impl_frame_ || 815 return needs_redraw_ || needs_one_begin_impl_frame_ ||
779 (needs_begin_main_frame_ && !defer_commits_); 816 (needs_begin_main_frame_ && !defer_commits_);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
875 SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const { 912 SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const {
876 if (settings_.using_synchronous_renderer_compositor) { 913 if (settings_.using_synchronous_renderer_compositor) {
877 // No deadline for synchronous compositor. 914 // No deadline for synchronous compositor.
878 return BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE; 915 return BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE;
879 } else if (wait_for_ready_to_draw_) { 916 } else if (wait_for_ready_to_draw_) {
880 // In browser compositor, wait for active tree to be rasterized. 917 // In browser compositor, wait for active tree to be rasterized.
881 DCHECK(settings_.commit_to_active_tree); 918 DCHECK(settings_.commit_to_active_tree);
882 return BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW; 919 return BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW;
883 } else if (ShouldTriggerBeginImplFrameDeadlineImmediately()) { 920 } else if (ShouldTriggerBeginImplFrameDeadlineImmediately()) {
884 return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE; 921 return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE;
885 } else if (needs_redraw_) { 922 } else if (needs_redraw_ && begin_frame_allows_latency_optimizations_) {
886 // We have an animation or fast input path on the impl thread that wants 923 // We have an animation or fast input path on the impl thread that wants
887 // to draw, so don't wait too long for a new active tree. 924 // to draw, so don't wait too long for a new active tree.
888 return BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR; 925 return BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR;
889 } else { 926 } else {
890 // The impl thread doesn't have anything it wants to draw and we are just 927 // The impl thread doesn't have anything it wants to draw and we are just
891 // waiting for a new active tree. In short we are blocked. 928 // waiting for a new active tree. In short we are blocked.
892 return BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE; 929 return BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE;
893 } 930 }
894 } 931 }
895 932
896 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately() 933 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately()
897 const { 934 const {
898 // If we just forced activation, we should end the deadline right now. 935 // If we just forced activation, we should end the deadline right now.
899 if (PendingActivationsShouldBeForced() && !has_pending_tree_) 936 if (PendingActivationsShouldBeForced() && !has_pending_tree_)
900 return true; 937 return true;
901 938
902 // Throttle the deadline on CompositorFrameAck since we wont draw and submit 939 // Throttle the deadline on CompositorFrameAck since we wont draw and submit
903 // anyway. 940 // anyway.
904 if (IsDrawThrottled()) 941 if (IsDrawThrottled())
905 return false; 942 return false;
906 943
907 if (active_tree_needs_first_draw_) 944 if (active_tree_needs_first_draw_)
908 return true; 945 return true;
909 946
947 // Immediately respond to the BeginFrame if the main frame isn't producing
948 // anything, e.g., after an aborted commit. We also check that we don't have a
949 // pending tree -- otherwise we should give it a chance to activate. We
950 // trigger an immediate deadline even if the impl thread doesn't want to draw
951 // anything either, because we don't want to stall the BeginFrame
952 // acknowledgment unnecessarily.
953 // TODO(skyostil): Revisit this when we have more accurate deadline estimates.
954 if (!CommitPending() && !has_pending_tree_)
955 return true;
956
910 if (!needs_redraw_) 957 if (!needs_redraw_)
911 return false; 958 return false;
912 959
913 // This is used to prioritize impl-thread draws when the main thread isn't
914 // producing anything, e.g., after an aborted commit. We also check that we
915 // don't have a pending tree -- otherwise we should give it a chance to
916 // activate.
917 // TODO(skyostil): Revisit this when we have more accurate deadline estimates.
918 if (!CommitPending() && !has_pending_tree_)
919 return true;
920
921 // Prioritize impl-thread draws in ImplLatencyTakesPriority mode. 960 // Prioritize impl-thread draws in ImplLatencyTakesPriority mode.
922 if (ImplLatencyTakesPriority()) 961 if (ImplLatencyTakesPriority())
923 return true; 962 return true;
924 963
925 return false; 964 return false;
926 } 965 }
927 966
928 bool SchedulerStateMachine::IsDrawThrottled() const { 967 bool SchedulerStateMachine::IsDrawThrottled() const {
929 return pending_submit_frames_ >= kMaxPendingSubmitFrames; 968 return pending_submit_frames_ >= kMaxPendingSubmitFrames;
930 } 969 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 tree_priority_ = tree_priority; 1038 tree_priority_ = tree_priority;
1000 scroll_handler_state_ = scroll_handler_state; 1039 scroll_handler_state_ = scroll_handler_state;
1001 } 1040 }
1002 1041
1003 void SchedulerStateMachine::SetCriticalBeginMainFrameToActivateIsFast( 1042 void SchedulerStateMachine::SetCriticalBeginMainFrameToActivateIsFast(
1004 bool is_fast) { 1043 bool is_fast) {
1005 critical_begin_main_frame_to_activate_is_fast_ = is_fast; 1044 critical_begin_main_frame_to_activate_is_fast_ = is_fast;
1006 } 1045 }
1007 1046
1008 bool SchedulerStateMachine::ImplLatencyTakesPriority() const { 1047 bool SchedulerStateMachine::ImplLatencyTakesPriority() const {
1048 // Wait for main frame if requested by BeginFrameArgs.
1049 if (!begin_frame_allows_latency_optimizations_)
1050 return false;
1051
1009 // Attempt to synchronize with the main thread if it has a scroll listener 1052 // Attempt to synchronize with the main thread if it has a scroll listener
1010 // and is fast. 1053 // and is fast.
1011 if (ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER == 1054 if (ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER ==
1012 scroll_handler_state_ && 1055 scroll_handler_state_ &&
1013 critical_begin_main_frame_to_activate_is_fast_) 1056 critical_begin_main_frame_to_activate_is_fast_)
1014 return false; 1057 return false;
1015 1058
1016 // Don't wait for the main thread if we are prioritizing smoothness. 1059 // Don't wait for the main thread if we are prioritizing smoothness.
1017 if (SMOOTHNESS_TAKES_PRIORITY == tree_priority_) 1060 if (SMOOTHNESS_TAKES_PRIORITY == tree_priority_)
1018 return true; 1061 return true;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1112 case COMPOSITOR_FRAME_SINK_ACTIVE: 1155 case COMPOSITOR_FRAME_SINK_ACTIVE:
1113 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_COMMIT: 1156 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_COMMIT:
1114 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_ACTIVATION: 1157 case COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_ACTIVATION:
1115 return true; 1158 return true;
1116 } 1159 }
1117 NOTREACHED(); 1160 NOTREACHED();
1118 return false; 1161 return false;
1119 } 1162 }
1120 1163
1121 } // namespace cc 1164 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler_state_machine.h ('k') | cc/surfaces/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698