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 1d77e09b3008c45af4978fa5199085aa8ee3a9e1..1e8af9c778bcba3ae962ba7d4c147d1b10774606 100644 |
| --- a/cc/scheduler/scheduler_state_machine.cc |
| +++ b/cc/scheduler/scheduler_state_machine.cc |
| @@ -19,7 +19,7 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) |
| current_frame_number_(0), |
| last_frame_number_where_begin_frame_sent_to_main_thread_(-1), |
| last_frame_number_where_draw_was_called_(-1), |
| - last_frame_number_where_tree_activation_attempted_(-1), |
| + last_frame_number_pending_tree_activated_(-1), |
| last_frame_number_where_update_visible_tiles_was_called_(-1), |
| consecutive_failed_draws_(0), |
| maximum_number_of_failed_draws_before_draw_is_forced_(3), |
| @@ -32,10 +32,13 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) |
| expect_immediate_begin_frame_for_main_thread_(false), |
| main_thread_needs_layer_textures_(false), |
| inside_begin_frame_(false), |
| + active_tree_has_been_drawn_(false), |
| + active_tree_is_null_(true), |
| visible_(false), |
| can_start_(false), |
| can_draw_(false), |
| has_pending_tree_(false), |
| + pending_tree_is_ready_for_activation_(false), |
| draw_if_possible_failed_(false), |
| texture_state_(LAYER_TEXTURE_STATE_UNLOCKED), |
| did_create_and_initialize_first_output_surface_(false) {} |
| @@ -98,8 +101,8 @@ const char* SchedulerStateMachine::ActionToString(Action action) { |
| return "ACTION_COMMIT"; |
| case ACTION_UPDATE_VISIBLE_TILES: |
| return "ACTION_UPDATE_VISIBLE_TILES"; |
| - case ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED: |
| - return "ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED"; |
| + case ACTION_ACTIVATE_PENDING_TREE: |
| + return "ACTION_ACTIVATE_PENDING_TREE"; |
| case ACTION_DRAW_IF_POSSIBLE: |
| return "ACTION_DRAW_IF_POSSIBLE"; |
| case ACTION_DRAW_FORCED: |
| @@ -162,8 +165,8 @@ scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const { |
| last_frame_number_where_begin_frame_sent_to_main_thread_); |
| minor_state->SetInteger("last_frame_number_where_draw_was_called", |
| last_frame_number_where_draw_was_called_); |
| - minor_state->SetInteger("last_frame_number_where_tree_activation_attempted", |
| - last_frame_number_where_tree_activation_attempted_); |
| + minor_state->SetInteger("last_frame_number_pending_tree_activated_", |
| + last_frame_number_pending_tree_activated_); |
| minor_state->SetInteger( |
| "last_frame_number_where_update_visible_tiles_was_called", |
| last_frame_number_where_update_visible_tiles_was_called_); |
| @@ -172,6 +175,9 @@ scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const { |
| minor_state->SetInteger( |
| "maximum_number_of_failed_draws_before_draw_is_forced", |
| maximum_number_of_failed_draws_before_draw_is_forced_); |
| + minor_state->SetBoolean("active_tree_has_been_drawn_", |
| + active_tree_has_been_drawn_); |
| + minor_state->SetBoolean("active_tree_is_null_", active_tree_is_null_); |
| minor_state->SetBoolean("needs_redraw", needs_redraw_); |
| minor_state->SetBoolean("swap_used_incomplete_tile", |
| swap_used_incomplete_tile_); |
| @@ -189,6 +195,8 @@ scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const { |
| minor_state->SetBoolean("can_start", can_start_); |
| minor_state->SetBoolean("can_draw", can_draw_); |
| minor_state->SetBoolean("has_pending_tree", has_pending_tree_); |
| + minor_state->SetBoolean("pending_tree_is_ready_for_activation_", |
| + pending_tree_is_ready_for_activation_); |
| minor_state->SetBoolean("draw_if_possible_failed", draw_if_possible_failed_); |
| minor_state->SetBoolean("did_create_and_initialize_first_output_surface", |
| did_create_and_initialize_first_output_surface_); |
| @@ -201,9 +209,9 @@ bool SchedulerStateMachine::HasDrawnThisFrame() const { |
| return current_frame_number_ == last_frame_number_where_draw_was_called_; |
| } |
| -bool SchedulerStateMachine::HasAttemptedTreeActivationThisFrame() const { |
| +bool SchedulerStateMachine::HasActivatedPendingTreeThisFrame() const { |
| return current_frame_number_ == |
| - last_frame_number_where_tree_activation_attempted_; |
| + last_frame_number_pending_tree_activated_; |
| } |
| bool SchedulerStateMachine::HasUpdatedVisibleTilesThisFrame() const { |
| @@ -244,12 +252,11 @@ void SchedulerStateMachine::HandleCommitInternal(bool commit_was_aborted) { |
| } |
| } |
| - // if we don't have to wait for activation, update needs_redraw now. |
| - if (!commit_results_in_pending_tree) { |
| - if (!commit_was_aborted) |
| - needs_redraw_ = true; |
| - if (expect_immediate_begin_frame_for_main_thread_) |
| + // Update state if we have a new active tree to draw. |
| + if (!commit_results_in_pending_tree && |
| + (!commit_was_aborted || expect_immediate_begin_frame_for_main_thread_)) { |
| needs_redraw_ = true; |
| + active_tree_has_been_drawn_ = false; |
| } |
| // This post-commit work is common to both completed and aborted commits. |
| @@ -308,9 +315,20 @@ bool SchedulerStateMachine::ShouldDraw() const { |
| return needs_redraw_; |
| } |
| -bool SchedulerStateMachine::ShouldAttemptTreeActivation() const { |
| - return has_pending_tree_ && inside_begin_frame_ && |
| - !HasAttemptedTreeActivationThisFrame(); |
| +bool SchedulerStateMachine::ShouldActivatePendingTree() const { |
| + // Some quick early outs. |
| + if (!inside_begin_frame_) |
| + return false; |
| + if (!has_pending_tree_) |
| + return false; |
| + if (HasActivatedPendingTreeThisFrame()) |
| + return false; |
| + |
| + if (!pending_tree_is_ready_for_activation_) |
| + return false; |
| + |
| + // We do not want to activate a second tree before drawing the first one. |
|
enne (OOO)
2013/08/23 17:54:09
Is this handled by the HasActivatedPendingTreeThis
brianderson
2013/08/23 20:51:59
There's some overlap, but there are cases where Ha
|
| + return active_tree_has_been_drawn_ || active_tree_is_null_; |
| } |
| bool SchedulerStateMachine::ShouldUpdateVisibleTiles() const { |
| @@ -319,7 +337,7 @@ bool SchedulerStateMachine::ShouldUpdateVisibleTiles() const { |
| if (HasUpdatedVisibleTilesThisFrame()) |
| return false; |
| - return ShouldAttemptTreeActivation() || ShouldDraw() || |
| + return ShouldActivatePendingTree() || ShouldDraw() || |
| swap_used_incomplete_tile_; |
| } |
| @@ -388,8 +406,8 @@ SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { |
| return ACTION_NONE; |
| if (ShouldUpdateVisibleTiles()) |
| return ACTION_UPDATE_VISIBLE_TILES; |
| - if (ShouldAttemptTreeActivation()) |
| - return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED; |
| + if (ShouldActivatePendingTree()) |
| + return ACTION_ACTIVATE_PENDING_TREE; |
| if (ShouldDraw()) { |
| return needs_forced_redraw_ ? ACTION_DRAW_FORCED |
| : ACTION_DRAW_IF_POSSIBLE; |
| @@ -401,8 +419,8 @@ SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { |
| case COMMIT_STATE_FRAME_IN_PROGRESS: |
| if (ShouldUpdateVisibleTiles()) |
| return ACTION_UPDATE_VISIBLE_TILES; |
| - if (ShouldAttemptTreeActivation()) |
| - return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED; |
| + if (ShouldActivatePendingTree()) |
| + return ACTION_ACTIVATE_PENDING_TREE; |
| if (ShouldDraw()) { |
| return needs_forced_redraw_ ? ACTION_DRAW_FORCED |
| : ACTION_DRAW_IF_POSSIBLE; |
| @@ -415,8 +433,8 @@ SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { |
| case COMMIT_STATE_WAITING_FOR_FIRST_DRAW: { |
| if (ShouldUpdateVisibleTiles()) |
| return ACTION_UPDATE_VISIBLE_TILES; |
| - if (ShouldAttemptTreeActivation()) |
| - return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED; |
| + if (ShouldActivatePendingTree()) |
| + return ACTION_ACTIVATE_PENDING_TREE; |
| if (ShouldDraw()) { |
| if (needs_forced_redraw_) |
| return ACTION_DRAW_FORCED; |
| @@ -431,8 +449,8 @@ SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { |
| case COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW: |
| if (ShouldUpdateVisibleTiles()) |
| return ACTION_UPDATE_VISIBLE_TILES; |
| - if (ShouldAttemptTreeActivation()) |
| - return ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED; |
| + if (ShouldActivatePendingTree()) |
| + return ACTION_ACTIVATE_PENDING_TREE; |
| if (needs_forced_redraw_) |
| return ACTION_DRAW_FORCED; |
| return ACTION_NONE; |
| @@ -451,9 +469,8 @@ void SchedulerStateMachine::UpdateState(Action action) { |
| current_frame_number_; |
| return; |
| - case ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED: |
| - last_frame_number_where_tree_activation_attempted_ = |
| - current_frame_number_; |
| + case ACTION_ACTIVATE_PENDING_TREE: |
| + last_frame_number_pending_tree_activated_ = current_frame_number_; |
| return; |
| case ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD: |
| @@ -519,6 +536,7 @@ void SchedulerStateMachine::UpdateStateOnDraw(bool did_swap) { |
| needs_redraw_ = false; |
| needs_forced_redraw_ = false; |
| draw_if_possible_failed_ = false; |
| + active_tree_has_been_drawn_ = true; |
| if (did_swap) |
| swap_used_incomplete_tile_ = false; |
| @@ -636,13 +654,25 @@ void SchedulerStateMachine::DidLoseOutputSurface() { |
| needs_redraw_ = false; |
| } |
| -void SchedulerStateMachine::SetHasPendingTree(bool has_pending_tree) { |
| +void SchedulerStateMachine::NotifyReadyToActivate() { |
| + if (has_pending_tree_) |
| + pending_tree_is_ready_for_activation_ = true; |
| +} |
| + |
| +void SchedulerStateMachine::SetHasTrees(bool has_pending_tree, |
| + bool active_tree_is_null) { |
| + active_tree_is_null_ = active_tree_is_null; |
| if (has_pending_tree_ && !has_pending_tree) { |
| // There is a new active tree. |
| + pending_tree_is_ready_for_activation_ = false; |
| + active_tree_has_been_drawn_ = false; |
| + needs_redraw_ = true; |
| + |
| if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION) |
| output_surface_state_ = OUTPUT_SURFACE_ACTIVE; |
| - |
| - needs_redraw_ = true; |
| + } else if (!has_pending_tree_ && has_pending_tree) { |
| + // There is a new pending tree. |
| + pending_tree_is_ready_for_activation_ = false; |
| } |
| has_pending_tree_ = has_pending_tree; |
| } |