has_pending_tree_(false),
pending_tree_is_ready_for_activation_(false),
active_tree_needs_first_draw_(false),
+ did_commit_after_animating_(false),
did_create_and_initialize_first_output_surface_(false),
impl_latency_takes_priority_(false),
skip_next_begin_main_frame_to_reduce_latency_(false),
skip_begin_main_frame_to_reduce_latency_(false),
- continuous_painting_(false) {
+ continuous_painting_(false),
+ impl_latency_takes_priority_on_battery_(false) {
}
const char* SchedulerStateMachine::OutputSurfaceStateToString(
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";
}
NOTREACHED();
return "???";
pending_tree_is_ready_for_activation_);
state->SetBoolean("active_tree_needs_first_draw",
active_tree_needs_first_draw_);
+ state->SetBoolean("did_commit_after_animating", did_commit_after_animating_);
state->SetBoolean("did_create_and_initialize_first_output_surface",
did_create_and_initialize_first_output_surface_);
state->SetBoolean("impl_latency_takes_priority",
state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency",
skip_next_begin_main_frame_to_reduce_latency_);
state->SetBoolean("continuous_painting", continuous_painting_);
+ state->SetBoolean("impl_latency_takes_priority_on_battery",
+ impl_latency_takes_priority_on_battery_);
state->EndDictionary();
}
skip_next_begin_main_frame_to_reduce_latency_ = false;
}
+bool SchedulerStateMachine::HasAnimatedThisFrame() const {
+ return last_frame_number_animate_performed_ == current_frame_number_;
+}
+
bool SchedulerStateMachine::HasSentBeginMainFrameThisFrame() const {
return current_frame_number_ ==
last_frame_number_begin_main_frame_sent_;
if (PendingDrawsShouldBeAborted())
return active_tree_needs_first_draw_;
+ // If a commit has occurred after the animate call, we need to call animate
+ // again before we should draw.
+ if (did_commit_after_animating_)
+ return false;
+
// After this line, we only want to send a swap request once per frame.
if (HasRequestedSwapThisFrame())
return false;
if (!can_draw_)
return false;
- if (last_frame_number_animate_performed_ == current_frame_number_)
+ // If a commit occurred after our last call, we need to do animation again.
+ if (HasAnimatedThisFrame() && !did_commit_after_animating_)
return false;
if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING &&
case ACTION_ANIMATE:
last_frame_number_animate_performed_ = current_frame_number_;
needs_animate_ = false;
+ did_commit_after_animating_ = false;
// TODO(skyostil): Instead of assuming this, require the client to tell
// us.
SetNeedsRedraw();
case ACTION_SEND_BEGIN_MAIN_FRAME:
DCHECK(!has_pending_tree_ ||
settings_.main_frame_before_activation_enabled);
- DCHECK(!active_tree_needs_first_draw_ ||
- settings_.main_frame_before_draw_enabled);
DCHECK(visible_);
commit_state_ = COMMIT_STATE_BEGIN_MAIN_FRAME_SENT;
needs_commit_ = false;
void SchedulerStateMachine::UpdateStateOnCommit(bool commit_was_aborted) {
commit_count_++;
+ if (!commit_was_aborted && HasAnimatedThisFrame())
+ did_commit_after_animating_ = true;
+
if (commit_was_aborted || settings_.main_frame_before_activation_enabled) {
commit_state_ = COMMIT_STATE_IDLE;
- } else if (settings_.main_frame_before_draw_enabled) {
+ } else {
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
if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW)
forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE;
- if (!has_pending_tree_ &&
- commit_state_ == COMMIT_STATE_WAITING_FOR_FIRST_DRAW) {
- commit_state_ = COMMIT_STATE_IDLE;
- }
-
needs_redraw_ = false;
active_tree_needs_first_draw_ = false;
}
void SchedulerStateMachine::SetSkipNextBeginMainFrameToReduceLatency() {
+ TRACE_EVENT_INSTANT0("cc",
+ "Scheduler: SkipNextBeginMainFrameToReduceLatency",
+ TRACE_EVENT_SCOPE_THREAD);
skip_next_begin_main_frame_to_reduce_latency_ = true;
}
if (impl_latency_takes_priority_)
return true;
+ // If we are on battery power and want to prioritize impl latency because
+ // we don't trust deadline tasks to execute at the right time.
+ if (impl_latency_takes_priority_on_battery_)
+ return true;
+
return false;
}