Index: cc/scheduler/scheduler_state_machine.cc |
diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc |
index 2fbeca2d8a992d87cd118a09a78eeb5db8b61d3b..99431633d86cc4fae7c00da0361dba5cce607aea 100644 |
--- a/cc/scheduler/scheduler_state_machine.cc |
+++ b/cc/scheduler/scheduler_state_machine.cc |
@@ -19,7 +19,8 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) |
output_surface_state_(OUTPUT_SURFACE_LOST), |
begin_impl_frame_state_(BEGIN_IMPL_FRAME_STATE_IDLE), |
commit_state_(COMMIT_STATE_IDLE), |
- forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), |
+ prepare_tiles_approach_(PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY), |
+ prepare_tiles_reason_(PREPARE_TILES_NOT_NEEDED), |
commit_count_(0), |
current_frame_number_(0), |
last_frame_number_animate_performed_(-1), |
@@ -32,18 +33,18 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) |
send_begin_main_frame_funnel_(false), |
invalidate_output_surface_funnel_(false), |
prepare_tiles_funnel_(0), |
- consecutive_checkerboard_animations_(0), |
max_pending_swaps_(1), |
pending_swaps_(0), |
needs_redraw_(false), |
+ last_draw_result_(DRAW_SUCCESS), |
needs_animate_(false), |
- needs_prepare_tiles_(false), |
needs_commit_(false), |
visible_(false), |
can_start_(false), |
can_draw_(false), |
has_pending_tree_(false), |
pending_tree_is_ready_for_activation_(false), |
+ requires_high_res_to_draw_(false), |
active_tree_needs_first_draw_(false), |
did_create_and_initialize_first_output_surface_(false), |
impl_latency_takes_priority_(false), |
@@ -104,6 +105,8 @@ const char* SchedulerStateMachine::BeginImplFrameDeadlineModeToString( |
return "BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR"; |
case BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE: |
return "BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE"; |
+ case BEGIN_IMPL_FRAME_DEADLINE_MODE_TRY_TO_AVOID_CHECKERBOARD: |
+ return "BEGIN_IMPL_FRAME_DEADLINE_MODE_TRY_TO_AVOID_CHECKERBOARD"; |
case BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW: |
return "BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW"; |
} |
@@ -130,17 +133,37 @@ const char* SchedulerStateMachine::CommitStateToString(CommitState state) { |
return "???"; |
} |
-const char* SchedulerStateMachine::ForcedRedrawOnTimeoutStateToString( |
- ForcedRedrawOnTimeoutState state) { |
- switch (state) { |
- case FORCED_REDRAW_STATE_IDLE: |
- return "FORCED_REDRAW_STATE_IDLE"; |
- case FORCED_REDRAW_STATE_WAITING_FOR_COMMIT: |
- return "FORCED_REDRAW_STATE_WAITING_FOR_COMMIT"; |
- case FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION: |
- return "FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION"; |
- case FORCED_REDRAW_STATE_WAITING_FOR_DRAW: |
- return "FORCED_REDRAW_STATE_WAITING_FOR_DRAW"; |
+const char* SchedulerStateMachine::PrepareTilesApproachToString( |
+ PrepareTilesApproach approach) { |
+ switch (approach) { |
+ case PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY: |
+ return "PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY"; |
+ case PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_WORK: |
+ return "PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_WORK"; |
+ case PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_PENDING_WORK: |
+ return "PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_PENDING_WORK"; |
+ case PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_PENDING_CANCELED_WORK: |
+ return "PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_PENDING_CANCELED_WORK"; |
+ } |
+ NOTREACHED(); |
+ return "???"; |
+} |
+ |
+const char* SchedulerStateMachine::PrepareTilesReasonToString( |
+ PrepareTilesReason reason) { |
+ switch (reason) { |
+ case PREPARE_TILES_NOT_NEEDED: |
+ return "PREPARE_TILES_NOT_NEEDED"; |
+ case PREPARE_TILES_REQUESTED: |
+ return "PREPARE_TILES_REQUESTED"; |
+ case PREPARE_TILES_NEEDED_FOR_COMMIT: |
+ return "PREPARE_TILES_NEEDED_FOR_COMMIT"; |
+ case PREPARE_TILES_NEEDED_FOR_ACTIVATION: |
+ return "PREPARE_TILES_NEEDED_FOR_ACTIVATION"; |
+ case PREPARE_TILES_NEEDED_FOR_ABORTED_DRAW: |
+ return "PREPARE_TILES_NEEDED_FOR_ABORTED_DRAW"; |
+ case PREPARE_TILES_NEEDED_TO_EVICT_TILES: |
+ return "PREPARE_TILES_NEEDED_TO_EVICT_TILES"; |
} |
NOTREACHED(); |
return "???"; |
@@ -190,10 +213,12 @@ void SchedulerStateMachine::AsValueInto( |
state->SetString("begin_impl_frame_state", |
BeginImplFrameStateToString(begin_impl_frame_state_)); |
state->SetString("commit_state", CommitStateToString(commit_state_)); |
- state->SetString("output_surface_state_", |
+ state->SetString("prepare_tiles_approach", |
+ PrepareTilesApproachToString(prepare_tiles_approach_)); |
+ state->SetString("prepare_tiles_reason", |
+ PrepareTilesReasonToString(prepare_tiles_reason_)); |
+ state->SetString("output_surface_state", |
OutputSurfaceStateToString(output_surface_state_)); |
- state->SetString("forced_redraw_state", |
- ForcedRedrawOnTimeoutStateToString(forced_redraw_state_)); |
state->EndDictionary(); |
state->BeginDictionary("minor_state"); |
@@ -214,13 +239,10 @@ void SchedulerStateMachine::AsValueInto( |
state->SetInteger("funnel: prepare_tiles_funnel", prepare_tiles_funnel_); |
state->SetBoolean("funnel: invalidate_output_surface_funnel", |
invalidate_output_surface_funnel_); |
- state->SetInteger("consecutive_checkerboard_animations", |
- consecutive_checkerboard_animations_); |
state->SetInteger("max_pending_swaps_", max_pending_swaps_); |
state->SetInteger("pending_swaps_", pending_swaps_); |
state->SetBoolean("needs_redraw", needs_redraw_); |
state->SetBoolean("needs_animate_", needs_animate_); |
- state->SetBoolean("needs_prepare_tiles", needs_prepare_tiles_); |
state->SetBoolean("needs_commit", needs_commit_); |
state->SetBoolean("visible", visible_); |
state->SetBoolean("can_start", can_start_); |
@@ -345,10 +367,6 @@ bool SchedulerStateMachine::ShouldDraw() const { |
if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) |
return false; |
- // Only handle forced redraws due to timeouts on the regular deadline. |
- if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) |
- return true; |
- |
return needs_redraw_; |
} |
@@ -430,11 +448,6 @@ bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { |
BeginFrameNeeded()) |
return false; |
- // We need a new commit for the forced redraw. This honors the |
- // single commit per interval because the result will be swapped to screen. |
- if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) |
- return true; |
- |
// We shouldn't normally accept commits if there isn't an OutputSurface. |
if (!HasInitializedOutputSurface()) |
return false; |
@@ -471,18 +484,41 @@ bool SchedulerStateMachine::ShouldCommit() const { |
} |
bool SchedulerStateMachine::ShouldPrepareTiles() const { |
- // PrepareTiles only really needs to be called immediately after commit |
- // and then periodically after that. Use a funnel to make sure we average |
- // one PrepareTiles per BeginImplFrame in the long run. |
- if (prepare_tiles_funnel_ > 0) |
- return false; |
+ // Handle the clear cut cases. |
+ switch (prepare_tiles_reason_) { |
+ case PREPARE_TILES_NOT_NEEDED: |
+ return false; |
+ case PREPARE_TILES_NEEDED_FOR_COMMIT: |
+ case PREPARE_TILES_NEEDED_FOR_ACTIVATION: |
+ case PREPARE_TILES_NEEDED_FOR_ABORTED_DRAW: |
+ case PREPARE_TILES_NEEDED_TO_EVICT_TILES: |
+ return true; |
+ case PREPARE_TILES_REQUESTED: |
+ break; |
+ } |
- // Limiting to once per-frame is not enough, since we only want to |
- // prepare tiles _after_ draws. |
- if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) |
- return false; |
+ switch (prepare_tiles_approach_) { |
+ case PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_WORK: |
+ case PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_PENDING_WORK: |
+ case PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_PENDING_CANCELED_WORK: |
+ // All of these approaches only handle requested PrepareTiles at the |
+ // start of a frame. |
+ return begin_impl_frame_state_ == |
+ BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING; |
+ case PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY: |
+ break; |
+ } |
- return needs_prepare_tiles_; |
+ DCHECK_EQ(PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY, prepare_tiles_approach_); |
+ DCHECK_EQ(PREPARE_TILES_REQUESTED, prepare_tiles_reason_); |
+ |
+ // Only PrepareTiles after a draw if we haven't already PreparedTiles this |
+ // frame. This takes PrepareTiles out of the critical path, but wil make the |
+ // NotifyReadyToDraw and NotifyReadyToActivate signals liars. |
+ bool did_not_prepare_tiles_at_end_of_frame = |
+ prepare_tiles_funnel_ == 0 && |
+ begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE; |
+ return did_not_prepare_tiles_at_end_of_frame; |
} |
bool SchedulerStateMachine::ShouldInvalidateOutputSurface() const { |
@@ -498,10 +534,11 @@ bool SchedulerStateMachine::ShouldInvalidateOutputSurface() const { |
if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) |
return false; |
+ // TODO(brianderson): Figure out what to do with this. |
// TODO(sunnyps): needs_prepare_tiles_ is needed here because PrepareTiles is |
// called only inside the deadline / draw phase. We could remove this if we |
// allowed PrepareTiles to happen in OnBeginImplFrame. |
- return needs_redraw_ || needs_prepare_tiles_; |
+ return needs_redraw_ || PrepareTilesPending(); |
} |
SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { |
@@ -514,10 +551,12 @@ SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { |
if (ShouldDraw()) { |
if (PendingDrawsShouldBeAborted()) |
return ACTION_DRAW_AND_SWAP_ABORT; |
- else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) |
- return ACTION_DRAW_AND_SWAP_FORCED; |
- else |
+ else if (requires_high_res_to_draw_ || |
+ prepare_tiles_approach_ == |
+ PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY) |
return ACTION_DRAW_AND_SWAP_IF_POSSIBLE; |
+ else |
+ return ACTION_DRAW_AND_SWAP_FORCED; |
} |
if (ShouldPrepareTiles()) |
return ACTION_PREPARE_TILES; |
@@ -620,13 +659,6 @@ void SchedulerStateMachine::UpdateStateOnCommit(bool commit_has_no_updates) { |
// mostly as if we are not impl-side-painting since there is no pending tree. |
has_pending_tree_ = settings_.impl_side_painting && !commit_has_no_updates; |
- // Update state related to forced draws. |
- if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_COMMIT) { |
- forced_redraw_state_ = has_pending_tree_ |
- ? FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION |
- : FORCED_REDRAW_STATE_WAITING_FOR_DRAW; |
- } |
- |
// Update the output surface state. |
DCHECK_NE(output_surface_state_, OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION); |
if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT) { |
@@ -638,11 +670,8 @@ void SchedulerStateMachine::UpdateStateOnCommit(bool commit_has_no_updates) { |
} |
} |
- // Update state if we have a new active tree to draw, or if the active tree |
- // was unchanged but we need to do a forced draw. |
- if (!has_pending_tree_ && |
- (!commit_has_no_updates || |
- forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)) { |
+ // Update state if we have a new active tree to draw. |
+ if (!has_pending_tree_) { |
needs_redraw_ = true; |
active_tree_needs_first_draw_ = true; |
} |
@@ -665,8 +694,10 @@ void SchedulerStateMachine::UpdateStateOnActivation() { |
if (output_surface_state_ == OUTPUT_SURFACE_WAITING_FOR_FIRST_ACTIVATION) |
output_surface_state_ = OUTPUT_SURFACE_ACTIVE; |
- if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION) |
- forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_DRAW; |
+ // Make sure to cancel any old active tree work if needed. |
+ if (prepare_tiles_approach_ == |
+ PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_PENDING_CANCELED_WORK) |
+ prepare_tiles_reason_ = PREPARE_TILES_NEEDED_FOR_ACTIVATION; |
has_pending_tree_ = false; |
pending_tree_is_ready_for_activation_ = false; |
@@ -675,9 +706,6 @@ void SchedulerStateMachine::UpdateStateOnActivation() { |
} |
void SchedulerStateMachine::UpdateStateOnDraw(bool did_request_swap) { |
- if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) |
- forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; |
- |
if (commit_state_ == COMMIT_STATE_WAITING_FOR_DRAW) |
commit_state_ = COMMIT_STATE_IDLE; |
@@ -690,10 +718,61 @@ void SchedulerStateMachine::UpdateStateOnDraw(bool did_request_swap) { |
did_request_swap_in_last_frame_ = true; |
last_frame_number_swap_requested_ = current_frame_number_; |
} |
+ |
+ switch (last_draw_result_) { |
+ case INVALID_RESULT: |
+ NOTREACHED() << "Uninitialized DrawResult."; |
+ break; |
+ |
+ case DRAW_ABORTED_CANT_DRAW: |
+ case DRAW_ABORTED_CONTEXT_LOST: |
+ NOTREACHED() << "Invalid return value from DrawAndSwapIfPossible:" |
+ << last_draw_result_; |
+ break; |
+ |
+ case DRAW_SUCCESS: |
+ break; |
+ |
+ case DRAW_ABORTED_MISSING_RASTER_OUTPUT_HIGH_RES: |
+ case DRAW_ABORTED_MISSING_RASTER_OUTPUT_ANY: |
+ TRACE_EVENT_INSTANT0("cc", "Raster missing output.", |
+ TRACE_EVENT_SCOPE_THREAD); |
+ prepare_tiles_reason_ = PREPARE_TILES_NEEDED_FOR_ABORTED_DRAW; |
+ if (prepare_tiles_approach_ == |
+ PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY) { |
+ prepare_tiles_approach_ = PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_WORK; |
+ } |
+ needs_redraw_ = true; |
+ // TODO(brianderson): reschedule the deadline. |
+ break; |
+ |
+ case DRAW_ABORTED_MISSING_RASTER_SOURCE: |
+ TRACE_EVENT_INSTANT0("cc", "Raster missing source.", |
+ TRACE_EVENT_SCOPE_THREAD); |
+ prepare_tiles_reason_ = PREPARE_TILES_NEEDED_FOR_ABORTED_DRAW; |
+ if (prepare_tiles_approach_ == |
+ PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY) { |
+ prepare_tiles_approach_ = PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_WORK; |
+ } |
+ // This is one of the few cases where we actively avoid drawing a commit. |
+ // Skipping draw of the commit can be better than a flash of checkerboard. |
+ active_tree_needs_first_draw_ = false; |
+ // We need a new commit to get an updated raster source. |
+ needs_commit_ = true; |
+ // TODO(brianderson): reschedule the deadline. |
+ break; |
+ } |
} |
void SchedulerStateMachine::UpdateStateOnPrepareTiles() { |
- needs_prepare_tiles_ = false; |
+ prepare_tiles_reason_ = PREPARE_TILES_NOT_NEEDED; |
+ |
+ active_tree_ready_to_draw_ = false; |
+ |
+ if (prepare_tiles_approach_ == PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY) |
+ prepare_tiles_funnel_++; |
+ else |
+ prepare_tiles_funnel_ = 0; |
} |
void SchedulerStateMachine::UpdateStateOnBeginOutputSurfaceCreation() { |
@@ -758,6 +837,13 @@ void SchedulerStateMachine::SetVideoNeedsBeginFrames( |
video_needs_begin_frames_ = video_needs_begin_frames; |
} |
+void SchedulerStateMachine::NotifyBeginFrameSourceActive(bool active) { |
+ // Upon becoming inactive, switch back to prioritizing latency. |
+ if (!active && |
+ prepare_tiles_approach_ == PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_WORK) |
+ prepare_tiles_approach_ = PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY; |
+} |
+ |
void SchedulerStateMachine::SetDeferCommits(bool defer_commits) { |
defer_commits_ = defer_commits; |
} |
@@ -765,11 +851,6 @@ void SchedulerStateMachine::SetDeferCommits(bool defer_commits) { |
// These are the cases where we require a BeginFrame message to make progress |
// on requested actions. |
bool SchedulerStateMachine::BeginFrameRequiredForAction() const { |
- // The forced draw respects our normal draw scheduling, so we need to |
- // request a BeginImplFrame for it. |
- if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) |
- return true; |
- |
return needs_animate_ || needs_redraw_ || (needs_commit_ && !defer_commits_); |
} |
@@ -799,7 +880,7 @@ bool SchedulerStateMachine::ProactiveBeginFrameWanted() const { |
// Changing priorities may allow us to activate (given the new priorities), |
// which may result in a new frame. |
- if (needs_prepare_tiles_) |
+ if (PrepareTilesPending()) |
return true; |
// If we just sent a swap request, it's likely that we are going to produce |
@@ -834,6 +915,15 @@ void SchedulerStateMachine::OnBeginImplFrame() { |
if (prepare_tiles_funnel_ > 0) |
prepare_tiles_funnel_--; |
+ // PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_WORK doesn't work well in |
+ // main thread low-latency mode. Transition back to |
+ // PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY if we just recovered |
+ // main-thread latency. |
+ if (skip_begin_main_frame_to_reduce_latency_ && |
+ prepare_tiles_approach_ == PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_WORK) { |
+ prepare_tiles_approach_ = PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY; |
+ } |
+ |
skip_begin_main_frame_to_reduce_latency_ = |
skip_next_begin_main_frame_to_reduce_latency_; |
skip_next_begin_main_frame_to_reduce_latency_ = false; |
@@ -867,17 +957,23 @@ SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const { |
return BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW; |
} else if (ShouldTriggerBeginImplFrameDeadlineImmediately()) { |
return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE; |
- } else if (needs_redraw_ && pending_swaps_ < max_pending_swaps_) { |
- // We have an animation or fast input path on the impl thread that wants |
- // to draw, so don't wait too long for a new active tree. |
- // If we are swap throttled we should wait until we are unblocked. |
- return BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR; |
- } else { |
- // The impl thread doesn't have anything it wants to draw and we are just |
- // waiting for a new active tree or we are swap throttled. In short we are |
- // blocked. |
- return BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE; |
} |
+ |
+ if (prepare_tiles_approach_ == PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY) { |
+ if (needs_redraw_ && pending_swaps_ < max_pending_swaps_) { |
+ // We have an animation or fast input path on the impl thread that wants |
+ // to draw, so don't wait too long for a new active tree. |
+ // If we are swap throttled we should wait until we are unblocked. |
+ return BEGIN_IMPL_FRAME_DEADLINE_MODE_REGULAR; |
+ } else { |
+ // The impl thread doesn't have anything it wants to draw and we are just |
+ // waiting for a new active tree or we are swap throttled. In short we are |
+ // blocked. |
+ return BEGIN_IMPL_FRAME_DEADLINE_MODE_LATE; |
+ } |
+ } |
+ |
+ return BEGIN_IMPL_FRAME_DEADLINE_MODE_TRY_TO_AVOID_CHECKERBOARD; |
} |
bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately() |
@@ -894,6 +990,11 @@ bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately() |
if (pending_swaps_ >= max_pending_swaps_) |
return false; |
+ // PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY is the only approach |
+ // where we want to trigger the deadline before NotifyReadyToDraw. |
+ if (prepare_tiles_approach_ != PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY) |
+ return active_tree_ready_to_draw_; |
+ |
if (active_tree_needs_first_draw_) |
return true; |
@@ -956,7 +1057,11 @@ bool SchedulerStateMachine::MainThreadIsInHighLatencyMode() const { |
return active_tree_needs_first_draw_; |
} |
-void SchedulerStateMachine::SetVisible(bool visible) { visible_ = visible; } |
+void SchedulerStateMachine::SetVisible(bool visible) { |
+ visible_ = visible; |
+ if (!visible) |
+ prepare_tiles_reason_ = PREPARE_TILES_NEEDED_TO_EVICT_TILES; |
+} |
void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; } |
@@ -971,10 +1076,24 @@ void SchedulerStateMachine::SetWaitForReadyToDraw() { |
wait_for_active_tree_ready_to_draw_ = true; |
} |
-void SchedulerStateMachine::SetNeedsPrepareTiles() { |
- if (!needs_prepare_tiles_) { |
- TRACE_EVENT0("cc", "SchedulerStateMachine::SetNeedsPrepareTiles"); |
- needs_prepare_tiles_ = true; |
+void SchedulerStateMachine::SetNeedsPrepareTiles(bool for_commit) { |
+ TRACE_EVENT0("cc", "SchedulerStateMachine::SetNeedsPrepareTiles"); |
+ switch (prepare_tiles_approach_) { |
+ case PREPARE_TILES_APPROACH_PRIORITIZE_LATENCY: |
+ case PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_PENDING_WORK: |
+ case PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_PENDING_CANCELED_WORK: |
+ if (for_commit) |
+ prepare_tiles_reason_ = PREPARE_TILES_NEEDED_FOR_COMMIT; |
+ else if (prepare_tiles_reason_ == PREPARE_TILES_NOT_NEEDED) |
+ prepare_tiles_reason_ = PREPARE_TILES_REQUESTED; |
+ break; |
+ |
+ case PREPARE_TILES_APPROACH_ACCURATE_ACTIVE_WORK: |
+ // We don't uncondititionally PrepareTiles immediately after a commit with |
+ // this approach. |
+ if (prepare_tiles_reason_ == PREPARE_TILES_NOT_NEEDED) |
+ prepare_tiles_reason_ = PREPARE_TILES_REQUESTED; |
+ break; |
} |
} |
@@ -1000,47 +1119,8 @@ void SchedulerStateMachine::SetImplLatencyTakesPriority( |
impl_latency_takes_priority_ = impl_latency_takes_priority; |
} |
-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_commit_ = 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_commit_ = true; |
- break; |
- } |
+void SchedulerStateMachine::SetDrawResult(DrawResult result) { |
+ last_draw_result_ = result; |
} |
void SchedulerStateMachine::SetNeedsCommit() { |
@@ -1074,12 +1154,6 @@ void SchedulerStateMachine::BeginMainFrameAborted(CommitEarlyOutReason reason) { |
} |
} |
-void SchedulerStateMachine::DidPrepareTiles() { |
- needs_prepare_tiles_ = false; |
- // "Fill" the PrepareTiles funnel. |
- prepare_tiles_funnel_++; |
-} |
- |
void SchedulerStateMachine::DidLoseOutputSurface() { |
if (output_surface_state_ == OUTPUT_SURFACE_LOST || |
output_surface_state_ == OUTPUT_SURFACE_CREATING) |
@@ -1096,6 +1170,13 @@ void SchedulerStateMachine::NotifyReadyToActivate() { |
void SchedulerStateMachine::NotifyReadyToDraw() { |
wait_for_active_tree_ready_to_draw_ = false; |
+ active_tree_ready_to_draw_ = true; |
+} |
+ |
+void SchedulerStateMachine::SetRequiresHighResToDraw(bool required) { |
+ if (requires_high_res_to_draw_ == required) |
+ return; |
+ requires_high_res_to_draw_ = required; |
} |
void SchedulerStateMachine::DidCreateAndInitializeOutputSurface() { |