Skip to content

Commit

Permalink
cc: Split animating and drawing into separate actions
Browse files Browse the repository at this point in the history
Split impl-side animating and drawing into separate actions. This is
needed to allow for the possibility of a commit between animating and
drawing so that the main thread gets a chance to consume the new
animation state. In particular this allows the main thread to
synchronize with a fling animation using an onscroll handler.

BUG=347366

Review URL: https://codereview.chromium.org/206793003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@266624 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
skyostil@chromium.org committed Apr 28, 2014
1 parent fda9e0f commit c232196
Show file tree
Hide file tree
Showing 19 changed files with 427 additions and 109 deletions.
1 change: 1 addition & 0 deletions cc/animation/layer_animation_controller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ void LayerAnimationController::UpdateState(bool start_ready_animations,
if (!HasActiveValueObserver())
return;

DCHECK(last_tick_time_);
if (start_ready_animations)
PromoteStartedAnimations(last_tick_time_, events);

Expand Down
2 changes: 1 addition & 1 deletion cc/input/input_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ class CC_EXPORT InputHandler {
base::TimeDelta duration) = 0;

// Request another callback to InputHandlerClient::Animate().
virtual void ScheduleAnimation() = 0;
virtual void SetNeedsAnimate() = 0;

virtual bool HaveTouchEventHandlersAt(const gfx::Point& viewport_point) = 0;

Expand Down
8 changes: 8 additions & 0 deletions cc/scheduler/scheduler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,11 @@ void Scheduler::SetNeedsRedraw() {
ProcessScheduledActions();
}

void Scheduler::SetNeedsAnimate() {
state_machine_.SetNeedsAnimate();
ProcessScheduledActions();
}

void Scheduler::SetNeedsManageTiles() {
DCHECK(!IsInsideAction(SchedulerStateMachine::ACTION_MANAGE_TILES));
state_machine_.SetNeedsManageTiles();
Expand Down Expand Up @@ -630,6 +635,9 @@ void Scheduler::ProcessScheduledActions() {
switch (action) {
case SchedulerStateMachine::ACTION_NONE:
break;
case SchedulerStateMachine::ACTION_ANIMATE:
client_->ScheduledActionAnimate();
break;
case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME:
client_->ScheduledActionSendBeginMainFrame();
break;
Expand Down
3 changes: 3 additions & 0 deletions cc/scheduler/scheduler.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class SchedulerClient {
virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapIfPossible() = 0;
virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapForced() = 0;
virtual DrawSwapReadbackResult ScheduledActionDrawAndReadback() = 0;
virtual void ScheduledActionAnimate() = 0;
virtual void ScheduledActionCommit() = 0;
virtual void ScheduledActionUpdateVisibleTiles() = 0;
virtual void ScheduledActionActivatePendingTree() = 0;
Expand Down Expand Up @@ -81,6 +82,8 @@ class CC_EXPORT Scheduler {

void SetNeedsRedraw();

void SetNeedsAnimate();

void SetNeedsManageTiles();

void SetMaxSwapsPending(int max);
Expand Down
51 changes: 45 additions & 6 deletions cc/scheduler/scheduler_state_machine.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
readback_state_(READBACK_STATE_IDLE),
commit_count_(0),
current_frame_number_(0),
last_frame_number_animate_performed_(-1),
last_frame_number_swap_performed_(-1),
last_frame_number_begin_main_frame_sent_(-1),
last_frame_number_update_visible_tiles_was_called_(-1),
Expand All @@ -30,6 +31,7 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
max_pending_swaps_(1),
pending_swaps_(0),
needs_redraw_(false),
needs_animate_(false),
needs_manage_tiles_(false),
swap_used_incomplete_tile_(false),
needs_commit_(false),
Expand All @@ -46,7 +48,8 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
skip_next_begin_main_frame_to_reduce_latency_(false),
skip_begin_main_frame_to_reduce_latency_(false),
continuous_painting_(false),
needs_back_to_back_readback_(false) {}
needs_back_to_back_readback_(false) {
}

const char* SchedulerStateMachine::OutputSurfaceStateToString(
OutputSurfaceState state) {
Expand Down Expand Up @@ -143,6 +146,8 @@ const char* SchedulerStateMachine::ActionToString(Action action) {
switch (action) {
case ACTION_NONE:
return "ACTION_NONE";
case ACTION_ANIMATE:
return "ACTION_ANIMATE";
case ACTION_SEND_BEGIN_MAIN_FRAME:
return "ACTION_SEND_BEGIN_MAIN_FRAME";
case ACTION_COMMIT:
Expand Down Expand Up @@ -216,6 +221,8 @@ scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const {
minor_state->SetInteger("commit_count", commit_count_);
minor_state->SetInteger("current_frame_number", current_frame_number_);

minor_state->SetInteger("last_frame_number_animate_performed",
last_frame_number_animate_performed_);
minor_state->SetInteger("last_frame_number_swap_performed",
last_frame_number_swap_performed_);
minor_state->SetInteger(
Expand All @@ -231,6 +238,7 @@ scoped_ptr<base::Value> SchedulerStateMachine::AsValue() const {
minor_state->SetInteger("max_pending_swaps_", max_pending_swaps_);
minor_state->SetInteger("pending_swaps_", pending_swaps_);
minor_state->SetBoolean("needs_redraw", needs_redraw_);
minor_state->SetBoolean("needs_animate_", needs_animate_);
minor_state->SetBoolean("needs_manage_tiles", needs_manage_tiles_);
minor_state->SetBoolean("swap_used_incomplete_tile",
swap_used_incomplete_tile_);
Expand Down Expand Up @@ -427,6 +435,20 @@ bool SchedulerStateMachine::ShouldUpdateVisibleTiles() const {
return false;
}

bool SchedulerStateMachine::ShouldAnimate() const {
if (!can_draw_)
return false;

if (last_frame_number_animate_performed_ == current_frame_number_)
return false;

if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING &&
begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
return false;

return needs_redraw_ || needs_animate_;
}

bool SchedulerStateMachine::ShouldSendBeginMainFrame() const {
if (!needs_commit_)
return false;
Expand Down Expand Up @@ -531,6 +553,8 @@ SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
return ACTION_ACTIVATE_PENDING_TREE;
if (ShouldCommit())
return ACTION_COMMIT;
if (ShouldAnimate())
return ACTION_ANIMATE;
if (ShouldDraw()) {
if (readback_state_ == READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK)
return ACTION_DRAW_AND_READBACK;
Expand Down Expand Up @@ -571,6 +595,14 @@ void SchedulerStateMachine::UpdateState(Action action) {
UpdateStateOnActivation();
return;

case ACTION_ANIMATE:
last_frame_number_animate_performed_ = current_frame_number_;
needs_animate_ = false;
// TODO(skyostil): Instead of assuming this, require the client to tell
// us.
SetNeedsRedraw();
return;

case ACTION_SEND_BEGIN_MAIN_FRAME:
DCHECK(!has_pending_tree_ ||
settings_.main_frame_before_activation_enabled);
Expand Down Expand Up @@ -783,17 +815,17 @@ bool SchedulerStateMachine::BeginFrameNeeded() const {
// To poll for state with the synchronous compositor without having to draw,
// we rely on ShouldPollForAnticipatedDrawTriggers instead.
if (!SupportsProactiveBeginFrame())
return BeginFrameNeededToDraw();
return BeginFrameNeededToAnimateOrDraw();

return BeginFrameNeededToDraw() || ProactiveBeginFrameWanted();
return BeginFrameNeededToAnimateOrDraw() || ProactiveBeginFrameWanted();
}

bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const {
// ShouldPollForAnticipatedDrawTriggers is what we use in place of
// ProactiveBeginFrameWanted when we are using the synchronous
// compositor.
if (!SupportsProactiveBeginFrame()) {
return !BeginFrameNeededToDraw() && ProactiveBeginFrameWanted();
return !BeginFrameNeededToAnimateOrDraw() && ProactiveBeginFrameWanted();
}

// Non synchronous compositors should rely on
Expand All @@ -812,8 +844,8 @@ bool SchedulerStateMachine::SupportsProactiveBeginFrame() const {
}

// These are the cases where we definitely (or almost definitely) have a
// new frame to draw and can draw.
bool SchedulerStateMachine::BeginFrameNeededToDraw() const {
// new frame to animate and/or draw and can draw.
bool SchedulerStateMachine::BeginFrameNeededToAnimateOrDraw() const {
// The output surface is the provider of BeginImplFrames, so we are not going
// to get them even if we ask for them.
if (!HasInitializedOutputSurface())
Expand All @@ -838,6 +870,9 @@ bool SchedulerStateMachine::BeginFrameNeededToDraw() const {
if (swap_used_incomplete_tile_)
return true;

if (needs_animate_)
return true;

return needs_redraw_;
}

Expand Down Expand Up @@ -1007,6 +1042,10 @@ void SchedulerStateMachine::SetCanDraw(bool can_draw) { can_draw_ = can_draw; }

void SchedulerStateMachine::SetNeedsRedraw() { needs_redraw_ = true; }

void SchedulerStateMachine::SetNeedsAnimate() {
needs_animate_ = true;
}

void SchedulerStateMachine::SetNeedsManageTiles() {
if (!needs_manage_tiles_) {
TRACE_EVENT0("cc",
Expand Down
9 changes: 8 additions & 1 deletion cc/scheduler/scheduler_state_machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class CC_EXPORT SchedulerStateMachine {

enum Action {
ACTION_NONE,
ACTION_ANIMATE,
ACTION_SEND_BEGIN_MAIN_FRAME,
ACTION_COMMIT,
ACTION_UPDATE_VISIBLE_TILES,
Expand Down Expand Up @@ -164,6 +165,9 @@ class CC_EXPORT SchedulerStateMachine {
void SetNeedsRedraw();
bool needs_redraw() const { return needs_redraw_; }

void SetNeedsAnimate();
bool needs_animate() const { return needs_animate_; }

// Indicates that manage-tiles is required. This guarantees another
// ManageTiles will occur shortly (even if no redraw is required).
void SetNeedsManageTiles();
Expand Down Expand Up @@ -248,12 +252,13 @@ class CC_EXPORT SchedulerStateMachine {
}

protected:
bool BeginFrameNeededToDraw() const;
bool BeginFrameNeededToAnimateOrDraw() const;
bool ProactiveBeginFrameWanted() const;

// True if we need to force activations to make forward progress.
bool PendingActivationsShouldBeForced() const;

bool ShouldAnimate() const;
bool ShouldBeginOutputSurfaceCreation() const;
bool ShouldDrawForced() const;
bool ShouldDraw() const;
Expand Down Expand Up @@ -286,6 +291,7 @@ class CC_EXPORT SchedulerStateMachine {

int commit_count_;
int current_frame_number_;
int last_frame_number_animate_performed_;
int last_frame_number_swap_performed_;
int last_frame_number_begin_main_frame_sent_;
int last_frame_number_update_visible_tiles_was_called_;
Expand All @@ -299,6 +305,7 @@ class CC_EXPORT SchedulerStateMachine {
int max_pending_swaps_;
int pending_swaps_;
bool needs_redraw_;
bool needs_animate_;
bool needs_manage_tiles_;
bool swap_used_incomplete_tile_;
bool needs_commit_;
Expand Down
Loading

0 comments on commit c232196

Please sign in to comment.