| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |