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

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

Issue 1247033007: cc: Abort frame when becoming invisible and waiting for ready to draw. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove race from test 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
« no previous file with comments | « cc/scheduler/scheduler_state_machine.h ('k') | cc/scheduler/scheduler_unittest.cc » ('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 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 main_thread_missed_last_deadline_(false), 50 main_thread_missed_last_deadline_(false),
51 skip_next_begin_main_frame_to_reduce_latency_(false), 51 skip_next_begin_main_frame_to_reduce_latency_(false),
52 continuous_painting_(false), 52 continuous_painting_(false),
53 children_need_begin_frames_(false), 53 children_need_begin_frames_(false),
54 defer_commits_(false), 54 defer_commits_(false),
55 video_needs_begin_frames_(false), 55 video_needs_begin_frames_(false),
56 last_commit_had_no_updates_(false), 56 last_commit_had_no_updates_(false),
57 wait_for_active_tree_ready_to_draw_(false), 57 wait_for_ready_to_draw_(false),
58 did_request_swap_in_last_frame_(false), 58 did_request_swap_in_last_frame_(false),
59 did_perform_swap_in_last_draw_(false) {} 59 did_perform_swap_in_last_draw_(false) {}
60 60
61 const char* SchedulerStateMachine::OutputSurfaceStateToString( 61 const char* SchedulerStateMachine::OutputSurfaceStateToString(
62 OutputSurfaceState state) { 62 OutputSurfaceState state) {
63 switch (state) { 63 switch (state) {
64 case OUTPUT_SURFACE_ACTIVE: 64 case OUTPUT_SURFACE_ACTIVE:
65 return "OUTPUT_SURFACE_ACTIVE"; 65 return "OUTPUT_SURFACE_ACTIVE";
66 case OUTPUT_SURFACE_LOST: 66 case OUTPUT_SURFACE_LOST:
67 return "OUTPUT_SURFACE_LOST"; 67 return "OUTPUT_SURFACE_LOST";
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 state->SetBoolean("needs_prepare_tiles", needs_prepare_tiles_); 224 state->SetBoolean("needs_prepare_tiles", needs_prepare_tiles_);
225 state->SetBoolean("needs_commit", needs_commit_); 225 state->SetBoolean("needs_commit", needs_commit_);
226 state->SetBoolean("visible", visible_); 226 state->SetBoolean("visible", visible_);
227 state->SetBoolean("can_start", can_start_); 227 state->SetBoolean("can_start", can_start_);
228 state->SetBoolean("can_draw", can_draw_); 228 state->SetBoolean("can_draw", can_draw_);
229 state->SetBoolean("has_pending_tree", has_pending_tree_); 229 state->SetBoolean("has_pending_tree", has_pending_tree_);
230 state->SetBoolean("pending_tree_is_ready_for_activation", 230 state->SetBoolean("pending_tree_is_ready_for_activation",
231 pending_tree_is_ready_for_activation_); 231 pending_tree_is_ready_for_activation_);
232 state->SetBoolean("active_tree_needs_first_draw", 232 state->SetBoolean("active_tree_needs_first_draw",
233 active_tree_needs_first_draw_); 233 active_tree_needs_first_draw_);
234 state->SetBoolean("wait_for_active_tree_ready_to_draw", 234 state->SetBoolean("wait_for_ready_to_draw", wait_for_ready_to_draw_);
235 wait_for_active_tree_ready_to_draw_);
236 state->SetBoolean("did_create_and_initialize_first_output_surface", 235 state->SetBoolean("did_create_and_initialize_first_output_surface",
237 did_create_and_initialize_first_output_surface_); 236 did_create_and_initialize_first_output_surface_);
238 state->SetBoolean("impl_latency_takes_priority", 237 state->SetBoolean("impl_latency_takes_priority",
239 impl_latency_takes_priority_); 238 impl_latency_takes_priority_);
240 state->SetBoolean("main_thread_missed_last_deadline", 239 state->SetBoolean("main_thread_missed_last_deadline",
241 main_thread_missed_last_deadline_); 240 main_thread_missed_last_deadline_);
242 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", 241 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency",
243 skip_next_begin_main_frame_to_reduce_latency_); 242 skip_next_begin_main_frame_to_reduce_latency_);
244 state->SetBoolean("continuous_painting", continuous_painting_); 243 state->SetBoolean("continuous_painting", continuous_painting_);
245 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_); 244 state->SetBoolean("children_need_begin_frames", children_need_begin_frames_);
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
637 636
638 if (commit_has_no_updates || settings_.main_frame_before_activation_enabled) { 637 if (commit_has_no_updates || settings_.main_frame_before_activation_enabled) {
639 commit_state_ = COMMIT_STATE_IDLE; 638 commit_state_ = COMMIT_STATE_IDLE;
640 } else { 639 } else {
641 commit_state_ = COMMIT_STATE_WAITING_FOR_ACTIVATION; 640 commit_state_ = COMMIT_STATE_WAITING_FOR_ACTIVATION;
642 } 641 }
643 642
644 // If the commit was aborted, then there is no pending tree. 643 // If the commit was aborted, then there is no pending tree.
645 has_pending_tree_ = !commit_has_no_updates; 644 has_pending_tree_ = !commit_has_no_updates;
646 645
646 wait_for_ready_to_draw_ =
647 !commit_has_no_updates && settings_.commit_to_active_tree;
648
647 // Update state related to forced draws. 649 // Update state related to forced draws.
648 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) { 650 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) {
649 forced_redraw_state_ = has_pending_tree_ 651 forced_redraw_state_ = has_pending_tree_
650 ? FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION 652 ? FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
651 : FORCED_REDRAW_STATE_WAITING_FOR_DRAW; 653 : FORCED_REDRAW_STATE_WAITING_FOR_DRAW;
652 } 654 }
653 655
654 // Update the output surface state. 656 // Update the output surface state.
655 DCHECK_NE(output_surface_state_, OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION); 657 DCHECK_NE(output_surface_state_, OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION);
656 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) { 658 if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) {
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() { 749 void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() {
748 TRACE_EVENT_INSTANT0("cc", 750 TRACE_EVENT_INSTANT0("cc",
749 "Scheduler: SkipNextBeginMainFrameToReduceLatency", 751 "Scheduler: SkipNextBeginMainFrameToReduceLatency",
750 TRACE_EVENT_SCOPE_THREAD); 752 TRACE_EVENT_SCOPE_THREAD);
751 skip_next_begin_main_frame_to_reduce_latency_ = true; 753 skip_next_begin_main_frame_to_reduce_latency_ = true;
752 } 754 }
753 755
754 bool SchedulerStateMachine::BeginFrameRequiredForChildren() const { 756 bool SchedulerStateMachine::BeginFrameRequiredForChildren() const {
755 return children_need_begin_frames_; 757 return children_need_begin_frames_;
756 } 758 }
759
757 bool SchedulerStateMachine::BeginFrameNeededForVideo() const { 760 bool SchedulerStateMachine::BeginFrameNeededForVideo() const {
758 return video_needs_begin_frames_; 761 return video_needs_begin_frames_;
759 } 762 }
760 763
761 bool SchedulerStateMachine::BeginFrameNeeded() const { 764 bool SchedulerStateMachine::BeginFrameNeeded() const {
762 // We can't handle BeginFrames when output surface isn't initialized. 765 // We can't handle BeginFrames when output surface isn't initialized.
763 // TODO(brianderson): Support output surface creation inside a BeginFrame. 766 // TODO(brianderson): Support output surface creation inside a BeginFrame.
764 if (!HasInitializedOutputSurface()) 767 if (!HasInitializedOutputSurface())
765 return false; 768 return false;
766 769
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
892 // funnels so that we don't perform any actions that we shouldn't. 895 // funnels so that we don't perform any actions that we shouldn't.
893 if (!BeginFrameNeeded()) 896 if (!BeginFrameNeeded())
894 send_begin_main_frame_funnel_ = true; 897 send_begin_main_frame_funnel_ = true;
895 } 898 }
896 899
897 SchedulerStateMachine::BeginImplFrameDeadlineMode 900 SchedulerStateMachine::BeginImplFrameDeadlineMode
898 SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const { 901 SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const {
899 if (settings_.using_synchronous_renderer_compositor) { 902 if (settings_.using_synchronous_renderer_compositor) {
900 // No deadline for synchronous compositor. 903 // No deadline for synchronous compositor.
901 return BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE; 904 return BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE;
902 } else if (wait_for_active_tree_ready_to_draw_) { 905 } else if (ShouldTriggerBeginImplFrameDeadlineImmediately()) {
906 return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE;
907 } else if (wait_for_ready_to_draw_) {
903 // When we are waiting for ready to draw signal, we do not wait to post a 908 // When we are waiting for ready to draw signal, we do not wait to post a
904 // deadline yet. 909 // deadline yet.
905 return BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW; 910 return BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW;
906 } else if (ShouldTriggerBeginImplFrameDeadlineImmediately()) {
907 return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE;
908 } else if (needs_redraw_ && !SwapThrottled()) { 911 } else if (needs_redraw_ && !SwapThrottled()) {
909 // We have an animation or fast input path on the impl thread that wants 912 // We have an animation or fast input path on the impl thread that wants
910 // to draw, so don't wait too long for a new active tree. 913 // to draw, so don't wait too long for a new active tree.
911 // If we are swap throttled we should wait until we are unblocked. 914 // If we are swap throttled we should wait until we are unblocked.
912 return BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR; 915 return BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR;
913 } else { 916 } else {
914 // The impl thread doesn't have anything it wants to draw and we are just 917 // The impl thread doesn't have anything it wants to draw and we are just
915 // waiting for a new active tree or we are swap throttled. In short we are 918 // waiting for a new active tree or we are swap throttled. In short we are
916 // blocked. 919 // blocked.
917 return BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE; 920 return BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE;
918 } 921 }
919 } 922 }
920 923
921 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately() 924 bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately()
922 const { 925 const {
923 if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)
924 return false;
925
926 // If we just forced activation, we should end the deadline right now. 926 // If we just forced activation, we should end the deadline right now.
927 if (PendingActivationsShouldBeForced() && !has_pending_tree_) 927 if (PendingActivationsShouldBeForced() && !has_pending_tree_)
928 return true; 928 return true;
929 929
930 // Do not trigger deadline immediately if we're waiting for READY_TO_DRAW
931 // unless it's one of the forced cases.
932 if (wait_for_ready_to_draw_)
933 return false;
934
930 // SwapAck throttle the deadline since we wont draw and swap anyway. 935 // SwapAck throttle the deadline since we wont draw and swap anyway.
931 if (SwapThrottled()) 936 if (SwapThrottled())
932 return false; 937 return false;
933 938
934 if (active_tree_needs_first_draw_) 939 if (active_tree_needs_first_draw_)
935 return true; 940 return true;
936 941
937 if (!needs_redraw_) 942 if (!needs_redraw_)
938 return false; 943 return false;
939 944
(...skipping 24 matching lines...) Expand all
964 if (visible_ == visible) 969 if (visible_ == visible)
965 return; 970 return;
966 971
967 visible_ = visible; 972 visible_ = visible;
968 973
969 if (visible) 974 if (visible)
970 main_thread_missed_last_deadline_ = false; 975 main_thread_missed_last_deadline_ = false;
971 976
972 // TODO(sunnyps): Change the funnel to a bool to avoid hacks like this. 977 // TODO(sunnyps): Change the funnel to a bool to avoid hacks like this.
973 prepare_tiles_funnel_ = 0; 978 prepare_tiles_funnel_ = 0;
979 wait_for_ready_to_draw_ = false;
974 } 980 }
975 981
976 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; } 982 void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; }
977 983
978 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; } 984 void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; }
979 985
980 void SchedulerStateMachine::SetNeedsAnimate() { 986 void SchedulerStateMachine::SetNeedsAnimate() {
981 needs_animate_ = true; 987 needs_animate_ = true;
982 } 988 }
983 989
984 void SchedulerStateMachine::SetWaitForReadyToDraw() {
985 wait_for_active_tree_ready_to_draw_ = true;
986 }
987
988 bool SchedulerStateMachine::OnlyImplSideUpdatesExpected() const { 990 bool SchedulerStateMachine::OnlyImplSideUpdatesExpected() const {
989 bool has_impl_updates = needs_redraw_ || needs_animate_; 991 bool has_impl_updates = needs_redraw_ || needs_animate_;
990 bool main_updates_expected = 992 bool main_updates_expected =
991 needs_commit_ || commit_state_ != COMMIT_STATE_IDLE || has_pending_tree_; 993 needs_commit_ || commit_state_ != COMMIT_STATE_IDLE || has_pending_tree_;
992 return has_impl_updates && !main_updates_expected; 994 return has_impl_updates && !main_updates_expected;
993 } 995 }
994 996
995 void SchedulerStateMachine::SetNeedsPrepareTiles() { 997 void SchedulerStateMachine::SetNeedsPrepareTiles() {
996 if (!needs_prepare_tiles_) { 998 if (!needs_prepare_tiles_) {
997 TRACE_EVENT0("cc", "SchedulerStateMachine::SetNeedsPrepareTiles"); 999 TRACE_EVENT0("cc", "SchedulerStateMachine::SetNeedsPrepareTiles");
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1101 // "Fill" the PrepareTiles funnel. 1103 // "Fill" the PrepareTiles funnel.
1102 prepare_tiles_funnel_++; 1104 prepare_tiles_funnel_++;
1103 } 1105 }
1104 1106
1105 void SchedulerStateMachine::DidLoseOutputSurface() { 1107 void SchedulerStateMachine::DidLoseOutputSurface() {
1106 if (output_surface_state_ == OUTPUT_SURFACE_LOST || 1108 if (output_surface_state_ == OUTPUT_SURFACE_LOST ||
1107 output_surface_state_ == OUTPUT_SURFACE_CREATING) 1109 output_surface_state_ == OUTPUT_SURFACE_CREATING)
1108 return; 1110 return;
1109 output_surface_state_ = OUTPUT_SURFACE_LOST; 1111 output_surface_state_ = OUTPUT_SURFACE_LOST;
1110 needs_redraw_ = false; 1112 needs_redraw_ = false;
1111 wait_for_active_tree_ready_to_draw_ = false; 1113 wait_for_ready_to_draw_ = false;
1112 } 1114 }
1113 1115
1114 void SchedulerStateMachine::NotifyReadyToActivate() { 1116 void SchedulerStateMachine::NotifyReadyToActivate() {
1115 if (has_pending_tree_) 1117 if (has_pending_tree_)
1116 pending_tree_is_ready_for_activation_ = true; 1118 pending_tree_is_ready_for_activation_ = true;
1117 } 1119 }
1118 1120
1119 void SchedulerStateMachine::NotifyReadyToDraw() { 1121 void SchedulerStateMachine::NotifyReadyToDraw() {
1120 wait_for_active_tree_ready_to_draw_ = false; 1122 wait_for_ready_to_draw_ = false;
1121 } 1123 }
1122 1124
1123 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() { 1125 void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() {
1124 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING); 1126 DCHECK_EQ(output_surface_state_, OUTPUT_SURFACE_CREATING);
1125 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT; 1127 output_surface_state_ = OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT;
1126 1128
1127 if (did_create_and_initialize_first_output_surface_) { 1129 if (did_create_and_initialize_first_output_surface_) {
1128 // TODO(boliu): See if we can remove this when impl-side painting is always 1130 // TODO(boliu): See if we can remove this when impl-side painting is always
1129 // on. Does anything on the main thread need to update after recreate? 1131 // on. Does anything on the main thread need to update after recreate?
1130 needs_commit_ = true; 1132 needs_commit_ = true;
(...skipping 18 matching lines...) Expand all
1149 case OUTPUT_SURFACE_ACTIVE: 1151 case OUTPUT_SURFACE_ACTIVE:
1150 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: 1152 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT:
1151 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: 1153 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION:
1152 return true; 1154 return true;
1153 } 1155 }
1154 NOTREACHED(); 1156 NOTREACHED();
1155 return false; 1157 return false;
1156 } 1158 }
1157 1159
1158 } // namespace cc 1160 } // namespace cc
OLDNEW
« no previous file with comments | « cc/scheduler/scheduler_state_machine.h ('k') | cc/scheduler/scheduler_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698