Chromium Code Reviews| 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/debug/trace_event_argument.h" | 8 #include "base/debug/trace_event_argument.h" |
| 9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 42 can_draw_(false), | 42 can_draw_(false), |
| 43 has_pending_tree_(false), | 43 has_pending_tree_(false), |
| 44 pending_tree_is_ready_for_activation_(false), | 44 pending_tree_is_ready_for_activation_(false), |
| 45 active_tree_needs_first_draw_(false), | 45 active_tree_needs_first_draw_(false), |
| 46 did_commit_after_animating_(false), | 46 did_commit_after_animating_(false), |
| 47 did_create_and_initialize_first_output_surface_(false), | 47 did_create_and_initialize_first_output_surface_(false), |
| 48 impl_latency_takes_priority_(false), | 48 impl_latency_takes_priority_(false), |
| 49 skip_next_begin_main_frame_to_reduce_latency_(false), | 49 skip_next_begin_main_frame_to_reduce_latency_(false), |
| 50 skip_begin_main_frame_to_reduce_latency_(false), | 50 skip_begin_main_frame_to_reduce_latency_(false), |
| 51 continuous_painting_(false), | 51 continuous_painting_(false), |
| 52 impl_latency_takes_priority_on_battery_(false) { | 52 impl_latency_takes_priority_on_battery_(false), |
| 53 defer_commits_(false) { | |
| 53 } | 54 } |
| 54 | 55 |
| 55 const char* SchedulerStateMachine::OutputSurfaceStateToString( | 56 const char* SchedulerStateMachine::OutputSurfaceStateToString( |
| 56 OutputSurfaceState state) { | 57 OutputSurfaceState state) { |
| 57 switch (state) { | 58 switch (state) { |
| 58 case OUTPUT_SURFACE_ACTIVE: | 59 case OUTPUT_SURFACE_ACTIVE: |
| 59 return "OUTPUT_SURFACE_ACTIVE"; | 60 return "OUTPUT_SURFACE_ACTIVE"; |
| 60 case OUTPUT_SURFACE_LOST: | 61 case OUTPUT_SURFACE_LOST: |
| 61 return "OUTPUT_SURFACE_LOST"; | 62 return "OUTPUT_SURFACE_LOST"; |
| 62 case OUTPUT_SURFACE_CREATING: | 63 case OUTPUT_SURFACE_CREATING: |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 234 impl_latency_takes_priority_); | 235 impl_latency_takes_priority_); |
| 235 state->SetBoolean("main_thread_is_in_high_latency_mode", | 236 state->SetBoolean("main_thread_is_in_high_latency_mode", |
| 236 MainThreadIsInHighLatencyMode()); | 237 MainThreadIsInHighLatencyMode()); |
| 237 state->SetBoolean("skip_begin_main_frame_to_reduce_latency", | 238 state->SetBoolean("skip_begin_main_frame_to_reduce_latency", |
| 238 skip_begin_main_frame_to_reduce_latency_); | 239 skip_begin_main_frame_to_reduce_latency_); |
| 239 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", | 240 state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency", |
| 240 skip_next_begin_main_frame_to_reduce_latency_); | 241 skip_next_begin_main_frame_to_reduce_latency_); |
| 241 state->SetBoolean("continuous_painting", continuous_painting_); | 242 state->SetBoolean("continuous_painting", continuous_painting_); |
| 242 state->SetBoolean("impl_latency_takes_priority_on_battery", | 243 state->SetBoolean("impl_latency_takes_priority_on_battery", |
| 243 impl_latency_takes_priority_on_battery_); | 244 impl_latency_takes_priority_on_battery_); |
| 245 state->SetBoolean("defer_commits", defer_commits_); | |
| 244 state->EndDictionary(); | 246 state->EndDictionary(); |
| 245 } | 247 } |
| 246 | 248 |
| 247 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { | 249 void SchedulerStateMachine::AdvanceCurrentFrameNumber() { |
| 248 current_frame_number_++; | 250 current_frame_number_++; |
| 249 | 251 |
| 250 // "Drain" the ManageTiles funnel. | 252 // "Drain" the ManageTiles funnel. |
| 251 if (manage_tiles_funnel_ > 0) | 253 if (manage_tiles_funnel_ > 0) |
| 252 manage_tiles_funnel_--; | 254 manage_tiles_funnel_--; |
| 253 | 255 |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 435 } | 437 } |
| 436 | 438 |
| 437 bool SchedulerStateMachine::CouldSendBeginMainFrame() const { | 439 bool SchedulerStateMachine::CouldSendBeginMainFrame() const { |
| 438 if (!needs_commit_) | 440 if (!needs_commit_) |
| 439 return false; | 441 return false; |
| 440 | 442 |
| 441 // We can not perform commits if we are not visible. | 443 // We can not perform commits if we are not visible. |
| 442 if (!visible_) | 444 if (!visible_) |
| 443 return false; | 445 return false; |
| 444 | 446 |
| 447 // We do not need new commits if it is deferred. | |
| 448 if (defer_commits_) | |
| 449 return false; | |
| 450 | |
| 445 return true; | 451 return true; |
| 446 } | 452 } |
| 447 | 453 |
| 448 bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { | 454 bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { |
| 449 if (!CouldSendBeginMainFrame()) | 455 if (!CouldSendBeginMainFrame()) |
| 450 return false; | 456 return false; |
| 451 | 457 |
| 452 // Only send BeginMainFrame when there isn't another commit pending already. | 458 // Only send BeginMainFrame when there isn't another commit pending already. |
| 453 if (commit_state_ != COMMIT_STATE_IDLE) | 459 if (commit_state_ != COMMIT_STATE_IDLE) |
| 454 return false; | 460 return false; |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 747 // Note: If SupportsProactiveBeginFrame is false, the scheduler should poll | 753 // Note: If SupportsProactiveBeginFrame is false, the scheduler should poll |
| 748 // for changes in it's draw state so it can request a BeginFrame when it's | 754 // for changes in it's draw state so it can request a BeginFrame when it's |
| 749 // actually ready. | 755 // actually ready. |
| 750 bool SchedulerStateMachine::SupportsProactiveBeginFrame() const { | 756 bool SchedulerStateMachine::SupportsProactiveBeginFrame() const { |
| 751 // It is undesirable to proactively request BeginFrames if we are | 757 // It is undesirable to proactively request BeginFrames if we are |
| 752 // using a synchronous compositor because we *must* draw for every | 758 // using a synchronous compositor because we *must* draw for every |
| 753 // BeginFrame, which could cause duplicate draws. | 759 // BeginFrame, which could cause duplicate draws. |
| 754 return !settings_.using_synchronous_renderer_compositor; | 760 return !settings_.using_synchronous_renderer_compositor; |
| 755 } | 761 } |
| 756 | 762 |
| 763 void SchedulerStateMachine::SetDeferCommits(bool defer_commits) { | |
| 764 defer_commits_ = defer_commits; | |
| 765 } | |
| 766 | |
| 757 // These are the cases where we definitely (or almost definitely) have a | 767 // These are the cases where we definitely (or almost definitely) have a |
| 758 // new frame to animate and/or draw and can draw. | 768 // new frame to animate and/or draw and can draw. |
| 759 bool SchedulerStateMachine::BeginFrameNeededToAnimateOrDraw() const { | 769 bool SchedulerStateMachine::BeginFrameNeededToAnimateOrDraw() const { |
| 760 // The output surface is the provider of BeginImplFrames, so we are not going | 770 // The output surface is the provider of BeginImplFrames, so we are not going |
| 761 // to get them even if we ask for them. | 771 // to get them even if we ask for them. |
| 762 if (!HasInitializedOutputSurface()) | 772 if (!HasInitializedOutputSurface()) |
| 763 return false; | 773 return false; |
| 764 | 774 |
| 775 // New BeginFrame should not be triggered during the commit is deferred. | |
| 776 if (defer_commits_) | |
|
danakj
2014/11/19 16:31:33
Why is the ShouldSendBeginMainFrame() change not e
brianderson
2014/11/19 19:55:07
Agree that this check isn't needed. Deferring comm
simonhong
2014/11/26 15:52:53
Yep, I think you're right.
Deferring commit should
| |
| 777 return false; | |
| 778 | |
| 765 // The forced draw respects our normal draw scheduling, so we need to | 779 // The forced draw respects our normal draw scheduling, so we need to |
| 766 // request a BeginImplFrame for it. | 780 // request a BeginImplFrame for it. |
| 767 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) | 781 if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) |
| 768 return true; | 782 return true; |
| 769 | 783 |
| 770 // We need to draw a more complete frame than we did the last BeginImplFrame, | 784 // We need to draw a more complete frame than we did the last BeginImplFrame, |
| 771 // so request another BeginImplFrame in anticipation that we will have | 785 // so request another BeginImplFrame in anticipation that we will have |
| 772 // additional visible tiles. | 786 // additional visible tiles. |
| 773 if (swap_used_incomplete_tile_) | 787 if (swap_used_incomplete_tile_) |
| 774 return true; | 788 return true; |
| 775 | 789 |
| 776 return needs_animate_ || needs_redraw_; | 790 return needs_animate_ || needs_redraw_; |
| 777 } | 791 } |
| 778 | 792 |
| 779 // These are cases where we are very likely to draw soon, but might not | 793 // These are cases where we are very likely to draw soon, but might not |
| 780 // actually have a new frame to draw when we receive the next BeginImplFrame. | 794 // actually have a new frame to draw when we receive the next BeginImplFrame. |
| 781 // Proactively requesting the BeginImplFrame helps hide the round trip latency | 795 // Proactively requesting the BeginImplFrame helps hide the round trip latency |
| 782 // of the SetNeedsBeginFrame request that has to go to the Browser. | 796 // of the SetNeedsBeginFrame request that has to go to the Browser. |
| 783 bool SchedulerStateMachine::ProactiveBeginFrameWanted() const { | 797 bool SchedulerStateMachine::ProactiveBeginFrameWanted() const { |
| 784 // The output surface is the provider of BeginImplFrames, | 798 // The output surface is the provider of BeginImplFrames, |
| 785 // so we are not going to get them even if we ask for them. | 799 // so we are not going to get them even if we ask for them. |
| 786 if (!HasInitializedOutputSurface()) | 800 if (!HasInitializedOutputSurface()) |
| 787 return false; | 801 return false; |
| 788 | 802 |
| 789 // Do not be proactive when invisible. | 803 // Do not be proactive when invisible. |
| 790 if (!visible_) | 804 if (!visible_) |
| 791 return false; | 805 return false; |
| 792 | 806 |
| 807 // New BeginFrame should not be triggered during the commit is deferred. | |
|
danakj
2014/11/19 16:31:33
ditto?
brianderson
2014/11/19 19:55:07
ditto.
simonhong
2014/11/26 15:52:53
Done.
| |
| 808 if (defer_commits_) | |
| 809 return false; | |
| 810 | |
| 793 // We should proactively request a BeginImplFrame if a commit is pending | 811 // We should proactively request a BeginImplFrame if a commit is pending |
| 794 // because we will want to draw if the commit completes quickly. | 812 // because we will want to draw if the commit completes quickly. |
| 795 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE) | 813 if (needs_commit_ || commit_state_ != COMMIT_STATE_IDLE) |
| 796 return true; | 814 return true; |
| 797 | 815 |
| 798 // If the pending tree activates quickly, we'll want a BeginImplFrame soon | 816 // If the pending tree activates quickly, we'll want a BeginImplFrame soon |
| 799 // to draw the new active tree. | 817 // to draw the new active tree. |
| 800 if (has_pending_tree_) | 818 if (has_pending_tree_) |
| 801 return true; | 819 return true; |
| 802 | 820 |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1101 static_cast<int>(begin_impl_frame_state_), | 1119 static_cast<int>(begin_impl_frame_state_), |
| 1102 static_cast<int>(commit_state_), | 1120 static_cast<int>(commit_state_), |
| 1103 has_pending_tree_ ? 'T' : 'F', | 1121 has_pending_tree_ ? 'T' : 'F', |
| 1104 pending_tree_is_ready_for_activation_ ? 'T' : 'F', | 1122 pending_tree_is_ready_for_activation_ ? 'T' : 'F', |
| 1105 active_tree_needs_first_draw_ ? 'T' : 'F', | 1123 active_tree_needs_first_draw_ ? 'T' : 'F', |
| 1106 max_pending_swaps_, | 1124 max_pending_swaps_, |
| 1107 pending_swaps_); | 1125 pending_swaps_); |
| 1108 } | 1126 } |
| 1109 | 1127 |
| 1110 } // namespace cc | 1128 } // namespace cc |
| OLD | NEW |