| 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/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
| 8 #include "base/format_macros.h" | 8 #include "base/format_macros.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 34 main_thread_needs_layer_textures_(false), | 34 main_thread_needs_layer_textures_(false), |
| 35 inside_poll_for_anticipated_draw_triggers_(false), | 35 inside_poll_for_anticipated_draw_triggers_(false), |
| 36 visible_(false), | 36 visible_(false), |
| 37 can_start_(false), | 37 can_start_(false), |
| 38 can_draw_(false), | 38 can_draw_(false), |
| 39 has_pending_tree_(false), | 39 has_pending_tree_(false), |
| 40 pending_tree_is_ready_for_activation_(false), | 40 pending_tree_is_ready_for_activation_(false), |
| 41 active_tree_needs_first_draw_(false), | 41 active_tree_needs_first_draw_(false), |
| 42 draw_if_possible_failed_(false), | 42 draw_if_possible_failed_(false), |
| 43 did_create_and_initialize_first_output_surface_(false), | 43 did_create_and_initialize_first_output_surface_(false), |
| 44 smoothness_takes_priority_(false) {} | 44 smoothness_takes_priority_(false), |
| 45 skip_begin_main_frame_to_reduce_latency_(false) {} |
| 45 | 46 |
| 46 const char* SchedulerStateMachine::OutputSurfaceStateToString( | 47 const char* SchedulerStateMachine::OutputSurfaceStateToString( |
| 47 OutputSurfaceState state) { | 48 OutputSurfaceState state) { |
| 48 switch (state) { | 49 switch (state) { |
| 49 case OUTPUT_SURFACE_ACTIVE: | 50 case OUTPUT_SURFACE_ACTIVE: |
| 50 return "OUTPUT_SURFACE_ACTIVE"; | 51 return "OUTPUT_SURFACE_ACTIVE"; |
| 51 case OUTPUT_SURFACE_LOST: | 52 case OUTPUT_SURFACE_LOST: |
| 52 return "OUTPUT_SURFACE_LOST"; | 53 return "OUTPUT_SURFACE_LOST"; |
| 53 case OUTPUT_SURFACE_CREATING: | 54 case OUTPUT_SURFACE_CREATING: |
| 54 return "OUTPUT_SURFACE_CREATING"; | 55 return "OUTPUT_SURFACE_CREATING"; |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 minor_state->SetBoolean("has_pending_tree", has_pending_tree_); | 253 minor_state->SetBoolean("has_pending_tree", has_pending_tree_); |
| 253 minor_state->SetBoolean("pending_tree_is_ready_for_activation", | 254 minor_state->SetBoolean("pending_tree_is_ready_for_activation", |
| 254 pending_tree_is_ready_for_activation_); | 255 pending_tree_is_ready_for_activation_); |
| 255 minor_state->SetBoolean("active_tree_needs_first_draw", | 256 minor_state->SetBoolean("active_tree_needs_first_draw", |
| 256 active_tree_needs_first_draw_); | 257 active_tree_needs_first_draw_); |
| 257 minor_state->SetBoolean("draw_if_possible_failed", draw_if_possible_failed_); | 258 minor_state->SetBoolean("draw_if_possible_failed", draw_if_possible_failed_); |
| 258 minor_state->SetBoolean("did_create_and_initialize_first_output_surface", | 259 minor_state->SetBoolean("did_create_and_initialize_first_output_surface", |
| 259 did_create_and_initialize_first_output_surface_); | 260 did_create_and_initialize_first_output_surface_); |
| 260 minor_state->SetBoolean("smoothness_takes_priority", | 261 minor_state->SetBoolean("smoothness_takes_priority", |
| 261 smoothness_takes_priority_); | 262 smoothness_takes_priority_); |
| 263 minor_state->SetBoolean("main_thread_is_in_high_latency_mode", |
| 264 MainThreadIsInHighLatencyMode()); |
| 265 minor_state->SetBoolean("skip_begin_main_frame_to_reduce_latency", |
| 266 skip_begin_main_frame_to_reduce_latency_); |
| 262 state->Set("minor_state", minor_state.release()); | 267 state->Set("minor_state", minor_state.release()); |
| 263 | 268 |
| 264 return state.PassAs<base::Value>(); | 269 return state.PassAs<base::Value>(); |
| 265 } | 270 } |
| 266 | 271 |
| 267 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const { | 272 bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const { |
| 268 return current_frame_number_ == | 273 return current_frame_number_ == |
| 269 last_frame_number_begin_main_frame_sent_; | 274 last_frame_number_begin_main_frame_sent_; |
| 270 } | 275 } |
| 271 | 276 |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 478 return true; | 483 return true; |
| 479 | 484 |
| 480 // After this point, we only start a commit once per frame. | 485 // After this point, we only start a commit once per frame. |
| 481 if (HasSentBeginMainFrameThisFrame()) | 486 if (HasSentBeginMainFrameThisFrame()) |
| 482 return false; | 487 return false; |
| 483 | 488 |
| 484 // We shouldn't normally accept commits if there isn't an OutputSurface. | 489 // We shouldn't normally accept commits if there isn't an OutputSurface. |
| 485 if (!HasInitializedOutputSurface()) | 490 if (!HasInitializedOutputSurface()) |
| 486 return false; | 491 return false; |
| 487 | 492 |
| 493 if (skip_begin_main_frame_to_reduce_latency_) |
| 494 return false; |
| 495 |
| 488 return true; | 496 return true; |
| 489 } | 497 } |
| 490 | 498 |
| 491 bool SchedulerStateMachine::ShouldCommit() const { | 499 bool SchedulerStateMachine::ShouldCommit() const { |
| 492 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT; | 500 return commit_state_ == COMMIT_STATE_READY_TO_COMMIT; |
| 493 } | 501 } |
| 494 | 502 |
| 495 bool SchedulerStateMachine::ShouldManageTiles() const { | 503 bool SchedulerStateMachine::ShouldManageTiles() const { |
| 496 // Limiting to once per-frame is not enough, since we only want to | 504 // Limiting to once per-frame is not enough, since we only want to |
| 497 // manage tiles _after_ draws. Polling for draw triggers and | 505 // manage tiles _after_ draws. Polling for draw triggers and |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 749 void SchedulerStateMachine::UpdateStateOnManageTiles() { | 757 void SchedulerStateMachine::UpdateStateOnManageTiles() { |
| 750 needs_manage_tiles_ = false; | 758 needs_manage_tiles_ = false; |
| 751 } | 759 } |
| 752 | 760 |
| 753 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() { | 761 void SchedulerStateMachine::SetMainThreadNeedsLayerTextures() { |
| 754 DCHECK(!main_thread_needs_layer_textures_); | 762 DCHECK(!main_thread_needs_layer_textures_); |
| 755 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD); | 763 DCHECK_NE(texture_state_, LAYER_TEXTURE_STATE_ACQUIRED_BY_MAIN_THREAD); |
| 756 main_thread_needs_layer_textures_ = true; | 764 main_thread_needs_layer_textures_ = true; |
| 757 } | 765 } |
| 758 | 766 |
| 767 void SchedulerStateMachine::SetSkipBeginMainFrameToReduceLatency(bool skip) { |
| 768 skip_begin_main_frame_to_reduce_latency_ = skip; |
| 769 } |
| 770 |
| 759 bool SchedulerStateMachine::BeginImplFrameNeeded() const { | 771 bool SchedulerStateMachine::BeginImplFrameNeeded() const { |
| 760 // Proactive BeginImplFrames are bad for the synchronous compositor because we | 772 // Proactive BeginImplFrames are bad for the synchronous compositor because we |
| 761 // have to draw when we get the BeginImplFrame and could end up drawing many | 773 // have to draw when we get the BeginImplFrame and could end up drawing many |
| 762 // duplicate frames if our new frame isn't ready in time. | 774 // duplicate frames if our new frame isn't ready in time. |
| 763 // To poll for state with the synchronous compositor without having to draw, | 775 // To poll for state with the synchronous compositor without having to draw, |
| 764 // we rely on ShouldPollForAnticipatedDrawTriggers instead. | 776 // we rely on ShouldPollForAnticipatedDrawTriggers instead. |
| 765 if (!SupportsProactiveBeginImplFrame()) | 777 if (!SupportsProactiveBeginImplFrame()) |
| 766 return BeginImplFrameNeededToDraw(); | 778 return BeginImplFrameNeededToDraw(); |
| 767 | 779 |
| 768 return BeginImplFrameNeededToDraw() || | 780 return BeginImplFrameNeededToDraw() || |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 912 if (commit_state_ == COMMIT_STATE_IDLE && !has_pending_tree_) | 924 if (commit_state_ == COMMIT_STATE_IDLE && !has_pending_tree_) |
| 913 return true; | 925 return true; |
| 914 | 926 |
| 915 // Prioritize impl-thread draws in smoothness mode. | 927 // Prioritize impl-thread draws in smoothness mode. |
| 916 if (smoothness_takes_priority_) | 928 if (smoothness_takes_priority_) |
| 917 return true; | 929 return true; |
| 918 | 930 |
| 919 return false; | 931 return false; |
| 920 } | 932 } |
| 921 | 933 |
| 934 bool SchedulerStateMachine::MainThreadIsInHighLatencyMode() const { |
| 935 // If we just sent a BeginMainFrame and haven't hit the deadline yet, the main |
| 936 // thread is in a low latency mode. |
| 937 if (last_frame_number_begin_main_frame_sent_ == current_frame_number_ && |
| 938 (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING || |
| 939 begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME)) |
| 940 return false; |
| 941 |
| 942 // If there's a commit in progress it must either be from the previous frame |
| 943 // or it started after the impl thread's deadline. In either case the main |
| 944 // thread is in high latency mode. |
| 945 if (commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS || |
| 946 commit_state_ == COMMIT_STATE_READY_TO_COMMIT) |
| 947 return true; |
| 948 |
| 949 // Similarly, if there's a pending tree the main thread is in high latency |
| 950 // mode, because either |
| 951 // it's from the previous frame |
| 952 // or |
| 953 // we're currently drawing the active tree and the pending tree will thus |
| 954 // only be drawn in the next frame. |
| 955 if (has_pending_tree_) |
| 956 return true; |
| 957 |
| 958 if (begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) { |
| 959 // Even if there's a new active tree to draw at the deadline or we've just |
| 960 // drawn it, it may have been triggered by a previous BeginImplFrame, in |
| 961 // which case the main thread is in a high latency mode. |
| 962 return (active_tree_needs_first_draw_ || |
| 963 last_frame_number_swap_performed_ == current_frame_number_) && |
| 964 last_frame_number_begin_main_frame_sent_ != current_frame_number_; |
| 965 } |
| 966 |
| 967 // If the active tree needs its first draw in any other state, we know the |
| 968 // main thread is in a high latency mode. |
| 969 return active_tree_needs_first_draw_; |
| 970 } |
| 971 |
| 922 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() { | 972 void SchedulerStateMachine::DidEnterPollForAnticipatedDrawTriggers() { |
| 923 current_frame_number_++; | 973 current_frame_number_++; |
| 924 inside_poll_for_anticipated_draw_triggers_ = true; | 974 inside_poll_for_anticipated_draw_triggers_ = true; |
| 925 } | 975 } |
| 926 | 976 |
| 927 void SchedulerStateMachine::DidLeavePollForAnticipatedDrawTriggers() { | 977 void SchedulerStateMachine::DidLeavePollForAnticipatedDrawTriggers() { |
| 928 inside_poll_for_anticipated_draw_triggers_ = false; | 978 inside_poll_for_anticipated_draw_triggers_ = false; |
| 929 } | 979 } |
| 930 | 980 |
| 931 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } | 981 void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1053 case OUTPUT_SURFACE_ACTIVE: | 1103 case OUTPUT_SURFACE_ACTIVE: |
| 1054 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: | 1104 case OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT: |
| 1055 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: | 1105 case OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION: |
| 1056 return true; | 1106 return true; |
| 1057 } | 1107 } |
| 1058 NOTREACHED(); | 1108 NOTREACHED(); |
| 1059 return false; | 1109 return false; |
| 1060 } | 1110 } |
| 1061 | 1111 |
| 1062 } // namespace cc | 1112 } // namespace cc |
| OLD | NEW |