Chromium Code Reviews| Index: cc/scheduler/scheduler_state_machine.cc |
| diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc |
| index 947637ddb0e86551714d4c741ef80ad37a689caa..f5a604d6df4c68d792e89c12e6600898c329718e 100644 |
| --- a/cc/scheduler/scheduler_state_machine.cc |
| +++ b/cc/scheduler/scheduler_state_machine.cc |
| @@ -87,6 +87,8 @@ const char* SchedulerStateMachine::CommitStateToString(CommitState state) { |
| return "COMMIT_STATE_FRAME_IN_PROGRESS"; |
| case COMMIT_STATE_READY_TO_COMMIT: |
| return "COMMIT_STATE_READY_TO_COMMIT"; |
| + case COMMIT_STATE_WAITING_FOR_ACTIVATION: |
| + return "COMMIT_STATE_WAITING_FOR_ACTIVATION"; |
| case COMMIT_STATE_WAITING_FOR_FIRST_DRAW: |
| return "COMMIT_STATE_WAITING_FOR_FIRST_DRAW"; |
| } |
| @@ -365,10 +367,8 @@ bool SchedulerStateMachine::ShouldDraw() const { |
| return false; |
| // Draw immediately for readbacks to unblock the main thread quickly. |
| - if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) { |
| - DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW); |
| + if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) |
| return true; |
| - } |
| // If we need to abort draws, we should do so ASAP since the draw could |
| // be blocking other important actions (like output surface initialization), |
| @@ -388,10 +388,8 @@ bool SchedulerStateMachine::ShouldDraw() const { |
| return false; |
| // Only handle forced redraws due to timeouts on the regular deadline. |
| - if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) { |
| - DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW); |
| + if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) |
| return true; |
| - } |
| return needs_redraw_; |
| } |
| @@ -456,9 +454,12 @@ bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { |
| if (commit_state_ != COMMIT_STATE_IDLE) |
| return false; |
| - // We can't accept a commit if we have a pending tree. |
| - if (has_pending_tree_) |
| + // Don't start commits early if we are prioritizing the active tree because |
| + // of smoothnes_takes_priority. |
|
enne (OOO)
2014/02/14 22:53:59
typo
|
| + if (smoothness_takes_priority_ && |
| + (has_pending_tree_ || active_tree_needs_first_draw_)) { |
| return false; |
| + } |
| // We want to handle readback commits immediately to unblock the main thread. |
| // Note: This BeginMainFrame will correspond to the replacement commit that |
| @@ -512,7 +513,23 @@ bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { |
| } |
| bool SchedulerStateMachine::ShouldCommit() const { |
| - return commit_state_ == COMMIT_STATE_READY_TO_COMMIT; |
| + if (commit_state_ != COMMIT_STATE_READY_TO_COMMIT) |
| + return false; |
| + |
| + // We must not finish the commit until the pending tree is free. |
| + if (has_pending_tree_) { |
| + DCHECK(settings_.start_commit_before_activate_enabled); |
| + return false; |
| + } |
| + |
| + // If not impl-side-painting, we must not finish the commit until the |
| + // previous commit has been drawn. |
| + if (active_tree_needs_first_draw_ && !settings_.impl_side_painting) { |
| + DCHECK(settings_.start_commit_before_draw_enabled); |
| + return false; |
| + } |
| + |
| + return true; |
| } |
| bool SchedulerStateMachine::IsCommitStateWaiting() const { |
| @@ -585,7 +602,10 @@ void SchedulerStateMachine::UpdateState(Action action) { |
| return; |
| case ACTION_SEND_BEGIN_MAIN_FRAME: |
| - DCHECK(!has_pending_tree_); |
| + DCHECK(!has_pending_tree_ || |
| + settings_.start_commit_before_activate_enabled); |
| + DCHECK(!active_tree_needs_first_draw_ || |
| + settings_.start_commit_before_draw_enabled); |
| DCHECK(visible_ || |
| readback_state_ == READBACK_STATE_NEEDS_BEGIN_MAIN_FRAME); |
| commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS; |
| @@ -642,6 +662,16 @@ void SchedulerStateMachine::UpdateState(Action action) { |
| void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { |
| commit_count_++; |
| + if (commit_was_aborted || settings_.start_commit_before_activate_enabled) { |
| + commit_state_ = COMMIT_STATE_IDLE; |
| + } else if (settings_.start_commit_before_draw_enabled) { |
| + commit_state_ = settings_.impl_side_painting |
| + ? COMMIT_STATE_WAITING_FOR_ACTIVATION |
| + : COMMIT_STATE_IDLE; |
| + } else { |
| + commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW; |
| + } |
| + |
| // If we are impl-side-painting but the commit was aborted, then we behave |
| // mostly as if we are not impl-side-painting since there is no pending tree. |
| has_pending_tree_ = settings_.impl_side_painting && !commit_was_aborted; |
| @@ -687,18 +717,6 @@ void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { |
| } |
| } |
| - // Update the commit state. We expect and wait for a draw if the commit |
| - // was not aborted or if we are in a readback or forced draw. |
| - if (!commit_was_aborted) { |
| - DCHECK(commit_state_ == COMMIT_STATE_READY_TO_COMMIT); |
| - commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW; |
| - } else if (readback_state_ != READBACK_STATE_IDLE || |
| - forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE) { |
| - commit_state_ = COMMIT_STATE_WAITING_FOR_FIRST_DRAW; |
| - } else { |
| - commit_state_ = COMMIT_STATE_IDLE; |
| - } |
| - |
| // Update state if we have a new active tree to draw, or if the active tree |
| // was unchanged but we need to do a readback or forced draw. |
| if (!has_pending_tree_ && |
| @@ -724,6 +742,9 @@ void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) { |
| } |
| void SchedulerStateMachine::UpdateStateOnActivation() { |
| + if (commit_state_ == COMMIT_STATE_WAITING_FOR_ACTIVATION) |
| + commit_state_ = COMMIT_STATE_IDLE; |
| + |
| // Update output surface state. |
| if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION) |
| output_surface_state_ = OUTPUT_SURFACE_ACTIVE; |
| @@ -750,8 +771,7 @@ void SchedulerStateMachine::UpdateStateOnDraw(bool did_swap) { |
| << *AsValue(); |
| if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK) { |
| - // The draw correspons to a readback commit. |
| - DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW); |
| + // The draw corresponds to a readback commit. |
| // We are blocking commits from the main thread until after this draw, so |
| // we should not have a pending tree. |
| DCHECK(!has_pending_tree_); |
| @@ -760,14 +780,12 @@ void SchedulerStateMachine::UpdateStateOnDraw(bool did_swap) { |
| commit_state_ = COMMIT_STATE_FRAME_IN_PROGRESS; |
| readback_state_ = READBACK_STATE_WAITING_FOR_REPLACEMENT_COMMIT; |
| } else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) { |
| - DCHECK_EQ(commit_state_, COMMIT_STATE_WAITING_FOR_FIRST_DRAW); |
| - commit_state_ = COMMIT_STATE_IDLE; |
| forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; |
| - } else if (commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW && |
| - !has_pending_tree_) { |
| - commit_state_ = COMMIT_STATE_IDLE; |
| } |
| + if (did_swap && commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW) |
| + commit_state_ = COMMIT_STATE_IDLE; |
| + |
| if (texture_state_ == LAYER_TEXTURE_STATE_ACQUIRED_BY_IMPL_THREAD) |
| texture_state_ = LAYER_TEXTURE_STATE_UNLOCKED; |
| @@ -962,6 +980,11 @@ bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineEarly() const { |
| } |
| bool SchedulerStateMachine::MainThreadIsInHighLatencyMode() const { |
| + // If a commit is pending before the previous commit has been drawn, we |
| + // are definitely in a high latency mode. |
| + if (CommitPending() && (active_tree_needs_first_draw_ || has_pending_tree_)) |
| + return true; |
| + |
| // If we just sent a BeginMainFrame and haven't hit the deadline yet, the main |
| // thread is in a low latency mode. |
| if (last_frame_number_begin_main_frame_sent_ == current_frame_number_ && |
| @@ -972,8 +995,7 @@ bool SchedulerStateMachine::MainThreadIsInHighLatencyMode() const { |
| // If there's a commit in progress it must either be from the previous frame |
| // or it started after the impl thread's deadline. In either case the main |
| // thread is in high latency mode. |
| - if (commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS || |
| - commit_state_ == COMMIT_STATE_READY_TO_COMMIT) |
| + if (CommitPending()) |
| return true; |
| // Similarly, if there's a pending tree the main thread is in high latency |
| @@ -1095,7 +1117,7 @@ void SchedulerStateMachine::SetNeedsForcedCommitForReadback() { |
| } |
| void SchedulerStateMachine::FinishCommit() { |
| - DCHECK(commit_state_ == COMMIT_STATE_FRAME_IN_PROGRESS) << *AsValue(); |
| + DCHECK(commit_state_ != COMMIT_STATE_IDLE) << *AsValue(); |
| commit_state_ = COMMIT_STATE_READY_TO_COMMIT; |
| } |