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 3330bd6d98c40a1cf1498329155ec00fe5f6ed45..c4851568e36f3b86a9cf2d12f460dadf2adb24f5 100644 |
| --- a/cc/scheduler/scheduler_state_machine.cc |
| +++ b/cc/scheduler/scheduler_state_machine.cc |
| @@ -28,11 +28,11 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) |
| current_frame_number_(0), |
| last_frame_number_animate_performed_(-1), |
| last_frame_number_swap_performed_(-1), |
| - last_frame_number_swap_requested_(-1), |
| + last_frame_number_draw_performed_(-1), |
| last_frame_number_begin_main_frame_sent_(-1), |
| last_frame_number_invalidate_output_surface_performed_(-1), |
| animate_funnel_(false), |
| - request_swap_funnel_(false), |
| + draw_funnel_(false), |
| send_begin_main_frame_funnel_(true), |
| invalidate_output_surface_funnel_(false), |
| prepare_tiles_funnel_(0), |
| @@ -62,8 +62,9 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) |
| video_needs_begin_frames_(false), |
| last_commit_had_no_updates_(false), |
| wait_for_ready_to_draw_(false), |
| - did_request_swap_in_last_frame_(false), |
| - did_perform_swap_in_last_draw_(false) {} |
| + did_draw_in_last_frame_(false), |
| + did_perform_swap_in_last_draw_(false), |
| + last_draw_result_(INVALID_RESULT) {} |
| const char* SchedulerStateMachine::OutputSurfaceStateToString( |
| OutputSurfaceState state) { |
| @@ -222,12 +223,12 @@ void SchedulerStateMachine::AsValueInto( |
| last_frame_number_animate_performed_); |
| state->SetInteger("last_frame_number_swap_performed", |
| last_frame_number_swap_performed_); |
| - state->SetInteger("last_frame_number_swap_requested", |
| - last_frame_number_swap_requested_); |
| + state->SetInteger("last_frame_number_draw_performed", |
| + last_frame_number_draw_performed_); |
| state->SetInteger("last_frame_number_begin_main_frame_sent", |
| last_frame_number_begin_main_frame_sent_); |
| state->SetBoolean("funnel: animate_funnel", animate_funnel_); |
| - state->SetBoolean("funnel: request_swap_funnel", request_swap_funnel_); |
| + state->SetBoolean("funnel: draw_funnel", draw_funnel_); |
| state->SetBoolean("funnel: send_begin_main_frame_funnel", |
| send_begin_main_frame_funnel_); |
| state->SetInteger("funnel: prepare_tiles_funnel", prepare_tiles_funnel_); |
| @@ -267,8 +268,7 @@ void SchedulerStateMachine::AsValueInto( |
| state->SetBoolean("video_needs_begin_frames", video_needs_begin_frames_); |
| state->SetBoolean("defer_commits", defer_commits_); |
| state->SetBoolean("last_commit_had_no_updates", last_commit_had_no_updates_); |
| - state->SetBoolean("did_request_swap_in_last_frame", |
| - did_request_swap_in_last_frame_); |
| + state->SetBoolean("did_draw_in_last_frame", did_draw_in_last_frame_); |
| state->SetBoolean("did_perform_swap_in_last_draw", |
| did_perform_swap_in_last_draw_); |
| state->EndDictionary(); |
| @@ -350,7 +350,7 @@ bool SchedulerStateMachine::ShouldDraw() const { |
| // Do not draw too many times in a single frame. It's okay that we don't check |
| // this before checking for aborted draws because aborted draws do not request |
| // a swap. |
| - if (request_swap_funnel_) |
| + if (draw_funnel_) |
| return false; |
| // Don't draw if we are waiting on the first commit after a surface. |
| @@ -668,22 +668,79 @@ void SchedulerStateMachine::WillActivate() { |
| needs_redraw_ = true; |
| } |
| -void SchedulerStateMachine::WillDraw(bool did_request_swap) { |
| +void SchedulerStateMachine::WillDrawInternal() { |
| + // We need to reset needs_redraw_ before we draw since the |
| + // draw itself might request another draw. |
| + needs_redraw_ = false; |
| + |
| + draw_funnel_ = true; |
| + active_tree_needs_first_draw_ = false; |
| + did_draw_in_last_frame_ = true; |
| + last_frame_number_draw_performed_ = current_frame_number_; |
| + |
| if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) |
| forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; |
| if (begin_main_frame_state_ == BEGIN_MAIN_FRAME_STATE_WAITING_FOR_DRAW) |
| begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_IDLE; |
| +} |
| - needs_redraw_ = false; |
| - active_tree_needs_first_draw_ = false; |
| +void SchedulerStateMachine::DidDrawInternal(DrawResult draw_result) { |
| + switch (draw_result) { |
| + case INVALID_RESULT: |
| + case DRAW_ABORTED_CANT_DRAW: |
| + case DRAW_ABORTED_CONTEXT_LOST: |
| + NOTREACHED() << "Invalid return DrawResult:" << draw_result; |
| + break; |
| + case DRAW_ABORTED_DRAINING_PIPELINE: |
|
sunnyps
2015/11/24 22:42:44
nit: Maybe DCHECK(!did_perform_swap_in_last_draw_)
brianderson
2015/11/24 23:19:38
Tried doing this. DRAW_ABORTED_DRAINING_PIPELINE c
|
| + case DRAW_SUCCESS: |
| + consecutive_checkerboard_animations_ = 0; |
| + forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; |
| + break; |
| + case DRAW_ABORTED_CHECKERBOARD_ANIMATIONS: |
| + DCHECK(!did_perform_swap_in_last_draw_); |
| + needs_begin_main_frame_ = true; |
| + needs_redraw_ = true; |
| + consecutive_checkerboard_animations_++; |
| - if (did_request_swap) { |
| - DCHECK(!request_swap_funnel_); |
| - request_swap_funnel_ = true; |
| - did_request_swap_in_last_frame_ = true; |
| - last_frame_number_swap_requested_ = current_frame_number_; |
| + if (consecutive_checkerboard_animations_ >= |
| + settings_.maximum_number_of_failed_draws_before_draw_is_forced && |
| + forced_redraw_state_ == FORCED_REDRAW_STATE_IDLE && |
| + settings_.timeout_and_draw_when_animation_checkerboards) { |
| + // We need to force a draw, but it doesn't make sense to do this until |
| + // we've committed and have new textures. |
| + forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT; |
| + } |
| + break; |
| + case DRAW_ABORTED_MISSING_HIGH_RES_CONTENT: |
| + DCHECK(!did_perform_swap_in_last_draw_); |
| + // It's not clear whether this missing content is because of missing |
| + // pictures (which requires a commit) or because of memory pressure |
| + // removing textures (which might not). To be safe, request a commit |
| + // anyway. |
| + needs_begin_main_frame_ = true; |
| + break; |
| } |
| + last_draw_result_ = draw_result; |
| +} |
| + |
| +void SchedulerStateMachine::WillDraw() { |
| + DCHECK(!draw_funnel_); |
| + WillDrawInternal(); |
| + |
| + // Assume the draw will succeed in case we get a DidSwapBuffers |
| + // before DidDraw is called. |
| + last_draw_result_ = DRAW_SUCCESS; |
|
sunnyps
2015/11/24 22:42:44
nit: Looks like the only reason to set this is for
brianderson
2015/11/24 23:19:38
True. Removed.
|
| +} |
| + |
| +void SchedulerStateMachine::DidDraw(DrawResult draw_result) { |
| + DidDrawInternal(draw_result); |
| +} |
| + |
| +void SchedulerStateMachine::AbortDrawAndSwap() { |
| + // Pretend like the draw was successful. |
| + WillDrawInternal(); |
| + DidDrawInternal(DRAW_ABORTED_DRAINING_PIPELINE); |
| } |
| void SchedulerStateMachine::WillPrepareTiles() { |
| @@ -799,12 +856,12 @@ bool SchedulerStateMachine::ProactiveBeginFrameWanted() const { |
| if (needs_prepare_tiles_) |
| return true; |
| - // If we just sent a swap request, it's likely that we are going to produce |
| + // If we just tried to DrawAndSwap, it's likely that we are going to produce |
| // another frame soon. This helps avoid negative glitches in our |
| // SetNeedsBeginFrame requests, which may propagate to the BeginImplFrame |
| // provider and get sampled at an inopportune time, delaying the next |
| // BeginImplFrame. |
| - if (did_request_swap_in_last_frame_) |
| + if (did_draw_in_last_frame_) |
| return true; |
| // If the last commit was aborted because of early out (no updates), we should |
| @@ -820,7 +877,7 @@ void SchedulerStateMachine::OnBeginImplFrame() { |
| current_frame_number_++; |
| last_commit_had_no_updates_ = false; |
| - did_request_swap_in_last_frame_ = false; |
| + did_draw_in_last_frame_ = false; |
| needs_one_begin_impl_frame_ = false; |
| // Clear funnels for any actions we perform during the frame. |
| @@ -843,7 +900,7 @@ void SchedulerStateMachine::OnBeginImplFrameDeadline() { |
| did_perform_swap_in_last_draw_ = false; |
| // Clear funnels for any actions we perform during the deadline. |
| - request_swap_funnel_ = false; |
| + draw_funnel_ = false; |
| // Allow one PrepareTiles per draw for synchronous compositor. |
| if (settings_.using_synchronous_renderer_compositor) { |
| @@ -979,11 +1036,12 @@ void SchedulerStateMachine::SetNeedsPrepareTiles() { |
| } |
| void SchedulerStateMachine::DidSwapBuffers() { |
| TRACE_EVENT_ASYNC_BEGIN0("cc", "Scheduler:pending_swaps", this); |
| + DCHECK_EQ(last_draw_result_, DRAW_SUCCESS); |
|
sunnyps
2015/11/24 22:42:44
nit: This DCHECK_EQ should be unnecessary.
brianderson
2015/11/24 23:19:38
Done.
|
| + DCHECK_LT(pending_swaps_, kMaxPendingSwaps); |
| + |
| pending_swaps_++; |
| swaps_with_current_output_surface_++; |
| - DCHECK_LE(pending_swaps_, kMaxPendingSwaps); |
| - |
| did_perform_swap_in_last_draw_ = true; |
| last_frame_number_swap_performed_ = current_frame_number_; |
| } |
| @@ -1020,49 +1078,6 @@ bool SchedulerStateMachine::ImplLatencyTakesPriority() const { |
| return false; |
| } |
| -void SchedulerStateMachine::DidDrawIfPossibleCompleted(DrawResult result) { |
| - switch (result) { |
| - case INVALID_RESULT: |
| - NOTREACHED() << "Uninitialized DrawResult."; |
| - break; |
| - case DRAW_ABORTED_CANT_DRAW: |
| - case DRAW_ABORTED_CONTEXT_LOST: |
| - NOTREACHED() << "Invalid return value from DrawAndSwapIfPossible:" |
| - << result; |
| - break; |
| - case DRAW_SUCCESS: |
| - consecutive_checkerboard_animations_ = 0; |
| - forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; |
| - break; |
| - case DRAW_ABORTED_CHECKERBOARD_ANIMATIONS: |
| - needs_redraw_ = true; |
| - |
| - // If we're already in the middle of a redraw, we don't need to |
| - // restart it. |
| - if (forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE) |
| - return; |
| - |
| - needs_begin_main_frame_ = true; |
| - consecutive_checkerboard_animations_++; |
| - if (settings_.timeout_and_draw_when_animation_checkerboards && |
| - consecutive_checkerboard_animations_ >= |
| - settings_.maximum_number_of_failed_draws_before_draw_is_forced) { |
| - consecutive_checkerboard_animations_ = 0; |
| - // We need to force a draw, but it doesn't make sense to do this until |
| - // we've committed and have new textures. |
| - forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT; |
| - } |
| - break; |
| - case DRAW_ABORTED_MISSING_HIGH_RES_CONTENT: |
| - // It's not clear whether this missing content is because of missing |
| - // pictures (which requires a commit) or because of memory pressure |
| - // removing textures (which might not). To be safe, request a commit |
| - // anyway. |
| - needs_begin_main_frame_ = true; |
| - break; |
| - } |
| -} |
| - |
| void SchedulerStateMachine::SetNeedsBeginMainFrame() { |
| needs_begin_main_frame_ = true; |
| } |