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..eedc6c384489e02379a67689073f42f30644580c 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,8 @@ 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_swap_in_last_frame_(false) {} |
const char* SchedulerStateMachine::OutputSurfaceStateToString( |
OutputSurfaceState state) { |
@@ -222,12 +222,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,10 +267,8 @@ 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_perform_swap_in_last_draw", |
- did_perform_swap_in_last_draw_); |
+ state->SetBoolean("did_draw_in_last_frame", did_draw_in_last_frame_); |
+ state->SetBoolean("did_swap_in_last_frame", did_swap_in_last_frame_); |
state->EndDictionary(); |
} |
@@ -350,7 +348,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. |
@@ -492,7 +490,7 @@ bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { |
// make it conditional on ImplLatencyTakesPriority. |
bool just_swapped_in_deadline = |
begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && |
- did_perform_swap_in_last_draw_; |
+ did_swap_in_last_frame_; |
if (SwapThrottled() && !just_swapped_in_deadline) |
return false; |
} |
@@ -668,24 +666,78 @@ 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: |
+ case DRAW_SUCCESS: |
+ consecutive_checkerboard_animations_ = 0; |
+ forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; |
+ break; |
+ case DRAW_ABORTED_CHECKERBOARD_ANIMATIONS: |
+ DCHECK(!did_swap_in_last_frame_); |
+ 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_swap_in_last_frame_); |
+ // 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::WillDraw() { |
+ DCHECK(!draw_funnel_); |
+ WillDrawInternal(); |
+} |
+ |
+void SchedulerStateMachine::DidDraw(DrawResult draw_result) { |
+ DidDrawInternal(draw_result); |
+} |
+ |
+void SchedulerStateMachine::AbortDrawAndSwap() { |
+ // Pretend like the draw was successful. |
+ // Note: We may abort at any time and cannot DCHECK that |
+ // we haven't drawn in or swapped in the last frame here. |
+ WillDrawInternal(); |
+ DidDrawInternal(DRAW_ABORTED_DRAINING_PIPELINE); |
+} |
+ |
void SchedulerStateMachine::WillPrepareTiles() { |
needs_prepare_tiles_ = false; |
} |
@@ -799,12 +851,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 +872,8 @@ 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; |
+ did_swap_in_last_frame_ = false; |
needs_one_begin_impl_frame_ = false; |
// Clear funnels for any actions we perform during the frame. |
@@ -840,10 +893,8 @@ void SchedulerStateMachine::OnBeginImplFrameDeadlinePending() { |
void SchedulerStateMachine::OnBeginImplFrameDeadline() { |
begin_impl_frame_state_ = BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; |
- 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,12 +1030,12 @@ void SchedulerStateMachine::SetNeedsPrepareTiles() { |
} |
void SchedulerStateMachine::DidSwapBuffers() { |
TRACE_EVENT_ASYNC_BEGIN0("cc", "Scheduler:pending_swaps", this); |
+ DCHECK_LT(pending_swaps_, kMaxPendingSwaps); |
+ |
pending_swaps_++; |
swaps_with_current_output_surface_++; |
- DCHECK_LE(pending_swaps_, kMaxPendingSwaps); |
- |
- did_perform_swap_in_last_draw_ = true; |
+ did_swap_in_last_frame_ = true; |
last_frame_number_swap_performed_ = current_frame_number_; |
} |
@@ -1020,49 +1071,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; |
} |