summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorskyostil@chromium.org <skyostil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-28 19:16:42 +0000
committerskyostil@chromium.org <skyostil@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-04-28 19:16:42 +0000
commitc23219664465d1fa295132ab4eede472b38ef6e9 (patch)
tree5b269f4ed61c1393773cfc8ff67aa8e5b6077773
parentfda9e0f2b7efdf5bcff04df08570852e88ff60d4 (diff)
downloadchromium_src-c23219664465d1fa295132ab4eede472b38ef6e9.zip
chromium_src-c23219664465d1fa295132ab4eede472b38ef6e9.tar.gz
chromium_src-c23219664465d1fa295132ab4eede472b38ef6e9.tar.bz2
cc: Split animating and drawing into separate actions
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
-rw-r--r--cc/animation/layer_animation_controller.cc1
-rw-r--r--cc/input/input_handler.h2
-rw-r--r--cc/scheduler/scheduler.cc8
-rw-r--r--cc/scheduler/scheduler.h3
-rw-r--r--cc/scheduler/scheduler_state_machine.cc51
-rw-r--r--cc/scheduler/scheduler_state_machine.h9
-rw-r--r--cc/scheduler/scheduler_state_machine_unittest.cc111
-rw-r--r--cc/scheduler/scheduler_unittest.cc52
-rw-r--r--cc/test/fake_layer_tree_host_impl_client.h1
-rw-r--r--cc/trees/layer_tree_host_impl.cc37
-rw-r--r--cc/trees/layer_tree_host_impl.h8
-rw-r--r--cc/trees/layer_tree_host_impl_unittest.cc46
-rw-r--r--cc/trees/layer_tree_host_unittest_animation.cc64
-rw-r--r--cc/trees/single_thread_proxy.cc4
-rw-r--r--cc/trees/single_thread_proxy.h1
-rw-r--r--cc/trees/thread_proxy.cc41
-rw-r--r--cc/trees/thread_proxy.h13
-rw-r--r--content/renderer/input/input_handler_proxy.cc6
-rw-r--r--content/renderer/input/input_handler_proxy_unittest.cc78
19 files changed, 427 insertions, 109 deletions
diff --git a/cc/animation/layer_animation_controller.cc b/cc/animation/layer_animation_controller.cc
index 464801c..5a9337c 100644
--- a/cc/animation/layer_animation_controller.cc
+++ b/cc/animation/layer_animation_controller.cc
@@ -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);
diff --git a/cc/input/input_handler.h b/cc/input/input_handler.h
index 774e011..e78a8d1 100644
--- a/cc/input/input_handler.h
+++ b/cc/input/input_handler.h
@@ -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;
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc
index df7f166..2417455 100644
--- a/cc/scheduler/scheduler.cc
+++ b/cc/scheduler/scheduler.cc
@@ -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();
@@ -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;
diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h
index 0d34f03..1e59192 100644
--- a/cc/scheduler/scheduler.h
+++ b/cc/scheduler/scheduler.h
@@ -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;
@@ -81,6 +82,8 @@ class CC_EXPORT Scheduler {
void SetNeedsRedraw();
+ void SetNeedsAnimate();
+
void SetNeedsManageTiles();
void SetMaxSwapsPending(int max);
diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc
index 647af71..0ddaa30 100644
--- a/cc/scheduler/scheduler_state_machine.cc
+++ b/cc/scheduler/scheduler_state_machine.cc
@@ -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),
@@ -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),
@@ -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) {
@@ -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:
@@ -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(
@@ -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_);
@@ -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;
@@ -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;
@@ -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);
@@ -783,9 +815,9 @@ 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 {
@@ -793,7 +825,7 @@ bool SchedulerStateMachine::ShouldPollForAnticipatedDrawTriggers() const {
// ProactiveBeginFrameWanted when we are using the synchronous
// compositor.
if (!SupportsProactiveBeginFrame()) {
- return !BeginFrameNeededToDraw() && ProactiveBeginFrameWanted();
+ return !BeginFrameNeededToAnimateOrDraw() && ProactiveBeginFrameWanted();
}
// Non synchronous compositors should rely on
@@ -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())
@@ -838,6 +870,9 @@ bool SchedulerStateMachine::BeginFrameNeededToDraw() const {
if (swap_used_incomplete_tile_)
return true;
+ if (needs_animate_)
+ return true;
+
return needs_redraw_;
}
@@ -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",
diff --git a/cc/scheduler/scheduler_state_machine.h b/cc/scheduler/scheduler_state_machine.h
index 2779264..e7d05e6 100644
--- a/cc/scheduler/scheduler_state_machine.h
+++ b/cc/scheduler/scheduler_state_machine.h
@@ -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,
@@ -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();
@@ -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;
@@ -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_;
@@ -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_;
diff --git a/cc/scheduler/scheduler_state_machine_unittest.cc b/cc/scheduler/scheduler_state_machine_unittest.cc
index 060269d..3dfe934 100644
--- a/cc/scheduler/scheduler_state_machine_unittest.cc
+++ b/cc/scheduler/scheduler_state_machine_unittest.cc
@@ -237,6 +237,7 @@ TEST(SchedulerStateMachineTest, MainFrameBeforeDrawDisabled) {
EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
state.OnBeginImplFrameDeadline();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
EXPECT_EQ(state.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE);
@@ -308,6 +309,7 @@ TEST(SchedulerStateMachineTest, MainFrameBeforeActivationEnabled) {
EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
state.OnBeginImplFrameDeadline();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
@@ -328,6 +330,7 @@ TEST(SchedulerStateMachineTest,
EXPECT_TRUE(state.RedrawPending());
EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
@@ -343,6 +346,7 @@ TEST(SchedulerStateMachineTest,
state.DidDrawIfPossibleCompleted(
DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_TRUE(state.RedrawPending());
@@ -362,6 +366,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawForMissingHighResNeedsCommit) {
EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
@@ -394,6 +399,7 @@ TEST(SchedulerStateMachineTest,
EXPECT_TRUE(state.RedrawPending());
EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
@@ -413,6 +419,7 @@ TEST(SchedulerStateMachineTest,
state.DidDrawIfPossibleCompleted(
DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_TRUE(state.RedrawPending());
@@ -443,6 +450,7 @@ void TestFailedDrawsEventuallyForceDrawAfterNextCommit(
// Then initiate a draw.
state.SetNeedsRedraw(true);
state.OnBeginImplFrameDeadline();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
@@ -465,6 +473,7 @@ void TestFailedDrawsEventuallyForceDrawAfterNextCommit(
// The redraw should be forced at the end of the next BeginImplFrame.
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
if (main_frame_before_draw_enabled) {
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
@@ -514,6 +523,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) {
// Then initiate a draw.
state.SetNeedsRedraw(true);
state.OnBeginImplFrameDeadline();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
@@ -566,6 +576,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedInNextBeginImplFrame) {
state.SetNeedsRedraw(true);
EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_TRUE(state.RedrawPending());
@@ -583,6 +594,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedInNextBeginImplFrame) {
// We should not be trying to draw again now, but we have a commit pending.
EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
// We should try to draw again at the end of the next BeginImplFrame on
@@ -606,6 +618,7 @@ TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) {
// Draw the first frame.
EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
@@ -623,6 +636,7 @@ TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) {
EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
@@ -686,6 +700,7 @@ TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) {
state.SetCommitState(all_commit_states[i]);
state.SetBeginImplFrameState(
SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
+
if (request_readback) {
state.SetNeedsForcedRedrawForReadback();
} else {
@@ -702,6 +717,9 @@ TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) {
} else {
expected_action =
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
+ EXPECT_EQ(state.NextAction(), SchedulerStateMachine::ACTION_ANIMATE)
+ << *state.AsValue();
+ state.UpdateState(state.NextAction());
}
// Case 1: needs_commit=false.
@@ -859,6 +877,7 @@ void TestSetNeedsCommitIsNotLost(bool main_frame_before_draw_enabled) {
// Finish the commit, then make sure we start the next commit immediately
// and draw on the next BeginImplFrame.
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
if (main_frame_before_draw_enabled) {
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
@@ -925,6 +944,7 @@ TEST(SchedulerStateMachineTest, TestFullCycle) {
// At BeginImplFrame deadline, draw.
state.OnBeginImplFrameDeadline();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
@@ -976,6 +996,7 @@ TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) {
// At BeginImplFrame deadline, draw.
state.OnBeginImplFrameDeadline();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
@@ -1084,6 +1105,7 @@ TEST(SchedulerStateMachineTest, AbortBeginMainFrameAndCancelCommit) {
// Start a new frame; draw because this is the first frame since output
// surface init'd.
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
@@ -1209,6 +1231,7 @@ TEST(SchedulerStateMachineTest,
// Once the context is recreated, whether we draw should be based on
// SetCanDraw.
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
@@ -1236,6 +1259,7 @@ TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) {
// Set damage and expect a draw.
state.SetNeedsRedraw(true);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
@@ -1300,6 +1324,7 @@ TEST(SchedulerStateMachineTest,
// Set damage and expect a draw.
state.SetNeedsRedraw(true);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
@@ -1361,6 +1386,7 @@ TEST(SchedulerStateMachineTest,
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
@@ -1524,6 +1550,7 @@ TEST(SchedulerStateMachineTest, DontMakeNewCommitAfterDrawingReplaceCommit) {
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
@@ -1628,6 +1655,7 @@ void TestForceCommitWhenReplacementActivationInProgress(
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
// Perform the draw & swap of replacement commit.
state.OnBeginImplFrameDeadline();
@@ -1667,6 +1695,7 @@ void TestForceCommitWhenReplacementActivationInProgress(
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
@@ -1737,6 +1766,7 @@ TEST(SchedulerStateMachineTest,
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
// Perform the draw & swap of replacement commit.
state.OnBeginImplFrameDeadline();
@@ -1974,6 +2004,7 @@ TEST(SchedulerStateMachineTest, TestTriggerDeadlineEarlyAfterAbortedCommit) {
state.SetNeedsCommit();
// We should start the commit normally.
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
@@ -2002,6 +2033,7 @@ TEST(SchedulerStateMachineTest, TestTriggerDeadlineEarlyForSmoothness) {
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
state.SetNeedsRedraw(true);
state.SetNeedsCommit();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
@@ -2012,5 +2044,84 @@ TEST(SchedulerStateMachineTest, TestTriggerDeadlineEarlyForSmoothness) {
EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
}
+TEST(SchedulerStateMachineTest, TestSetNeedsAnimate) {
+ SchedulerSettings settings;
+ settings.impl_side_painting = true;
+ StateMachine state(settings);
+ state.SetCanStart();
+ state.UpdateState(state.NextAction());
+ state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
+ state.SetVisible(true);
+ state.SetCanDraw(true);
+
+ // Test requesting an animation that, when run, causes us to draw.
+ state.SetNeedsAnimate();
+ EXPECT_TRUE(state.BeginFrameNeeded());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+
+ state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
+
+ state.OnBeginImplFrameDeadlinePending();
+ state.OnBeginImplFrameDeadline();
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
+}
+
+TEST(SchedulerStateMachineTest, TestAnimateBeforeCommit) {
+ SchedulerSettings settings;
+ settings.impl_side_painting = true;
+ StateMachine state(settings);
+ state.SetCanStart();
+ state.UpdateState(state.NextAction());
+ state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
+ state.SetVisible(true);
+ state.SetCanDraw(true);
+
+ // Check that animations are updated before we start a commit.
+ state.SetNeedsAnimate();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+ state.SetNeedsCommit();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+ EXPECT_TRUE(state.BeginFrameNeeded());
+
+ state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
+
+ state.OnBeginImplFrameDeadlinePending();
+ state.OnBeginImplFrameDeadline();
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
+}
+
+TEST(SchedulerStateMachineTest, TestSetNeedsAnimateAfterAnimate) {
+ SchedulerSettings settings;
+ settings.impl_side_painting = true;
+ StateMachine state(settings);
+ state.SetCanStart();
+ state.UpdateState(state.NextAction());
+ state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
+ state.SetVisible(true);
+ state.SetCanDraw(true);
+
+ // Test requesting an animation after we have already animated during this
+ // frame.
+ state.SetNeedsRedraw(true);
+ EXPECT_TRUE(state.BeginFrameNeeded());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+
+ state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
+
+ state.SetNeedsAnimate();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+
+ state.OnBeginImplFrameDeadline();
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
+}
+
} // namespace
} // namespace cc
diff --git a/cc/scheduler/scheduler_unittest.cc b/cc/scheduler/scheduler_unittest.cc
index a5d279b..921b94a 100644
--- a/cc/scheduler/scheduler_unittest.cc
+++ b/cc/scheduler/scheduler_unittest.cc
@@ -109,6 +109,10 @@ class FakeSchedulerClient : public SchedulerClient {
actions_.push_back("ScheduledActionSendBeginMainFrame");
states_.push_back(scheduler_->StateAsValue().release());
}
+ virtual void ScheduledActionAnimate() OVERRIDE {
+ actions_.push_back("ScheduledActionAnimate");
+ states_.push_back(scheduler_->StateAsValue().release());
+ }
virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapIfPossible()
OVERRIDE {
actions_.push_back("ScheduledActionDrawAndSwapIfPossible");
@@ -286,7 +290,8 @@ TEST(SchedulerTest, RequestCommit) {
// BeginImplFrame should prepare the draw.
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
+ EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_TRUE(client.needs_begin_frame());
client.Reset();
@@ -348,7 +353,8 @@ TEST(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
client.Reset();
client.task_runner().RunPendingTasks(); // Run posted deadline.
- EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 1);
+ EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2);
EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
// Because we just swapped, the Scheduler should also request the next
@@ -371,7 +377,8 @@ TEST(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
client.Reset();
client.task_runner().RunPendingTasks(); // Run posted deadline.
- EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 1);
+ EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2);
EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_TRUE(client.needs_begin_frame());
client.Reset();
@@ -738,7 +745,8 @@ TEST(SchedulerTest, ManageTiles) {
// the deadline task.
client.Reset();
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
+ EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
// On the deadline, he actions should have occured in the right order.
@@ -765,7 +773,8 @@ TEST(SchedulerTest, ManageTiles) {
// the deadline task.
client.Reset();
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
+ EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
// Draw. The draw will trigger SetNeedsManageTiles, and
@@ -832,7 +841,8 @@ TEST(SchedulerTest, ManageTilesOncePerFrame) {
scheduler->SetNeedsRedraw();
client.Reset();
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
+ EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_TRUE(scheduler->ManageTilesPending());
@@ -853,7 +863,8 @@ TEST(SchedulerTest, ManageTilesOncePerFrame) {
scheduler->SetNeedsRedraw();
client.Reset();
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
+ EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
client.Reset();
@@ -875,7 +886,8 @@ TEST(SchedulerTest, ManageTilesOncePerFrame) {
scheduler->SetNeedsRedraw();
client.Reset();
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
+ EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_TRUE(scheduler->ManageTilesPending());
@@ -897,7 +909,8 @@ TEST(SchedulerTest, ManageTilesOncePerFrame) {
scheduler->SetNeedsRedraw();
client.Reset();
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
+ EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_TRUE(scheduler->ManageTilesPending());
@@ -915,7 +928,8 @@ TEST(SchedulerTest, ManageTilesOncePerFrame) {
scheduler->SetNeedsRedraw();
client.Reset();
scheduler->BeginFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
+ EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
client.Reset();
@@ -1171,7 +1185,8 @@ TEST(SchedulerTest, BeginRetroFrame) {
// BeginImplFrame should prepare the draw.
client.task_runner().RunPendingTasks(); // Run posted BeginRetroFrame.
- EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
+ EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_TRUE(client.needs_begin_frame());
client.Reset();
@@ -1244,7 +1259,8 @@ TEST(SchedulerTest, BeginRetroFrame_SwapThrottled) {
// Swapping will put us into a swap throttled state.
client.task_runner().RunPendingTasks(); // Run posted deadline.
- EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 1);
+ EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2);
EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_TRUE(client.needs_begin_frame());
client.Reset();
@@ -1276,7 +1292,8 @@ TEST(SchedulerTest, BeginRetroFrame_SwapThrottled) {
// BeginImplFrame deadline should draw.
scheduler->SetNeedsRedraw();
client.task_runner().RunPendingTasks(); // Run posted deadline.
- EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 1);
+ EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2);
EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_TRUE(client.needs_begin_frame());
client.Reset();
@@ -1328,7 +1345,8 @@ void BeginFramesNotFromClient(bool begin_frame_scheduling_enabled,
// BeginImplFrame should prepare the draw.
client.task_runner().RunPendingTasks(); // Run posted BeginFrame.
- EXPECT_SINGLE_ACTION("WillBeginImplFrame", client);
+ EXPECT_ACTION("WillBeginImplFrame", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionAnimate", client, 1, 2);
EXPECT_TRUE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_FALSE(client.needs_begin_frame());
client.Reset();
@@ -1417,7 +1435,8 @@ void BeginFramesNotFromClient_SwapThrottled(bool begin_frame_scheduling_enabled,
// Swapping will put us into a swap throttled state.
client.task_runner().RunPendingTasks(); // Run posted deadline.
- EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 1);
+ EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2);
EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_FALSE(client.needs_begin_frame());
client.Reset();
@@ -1441,7 +1460,8 @@ void BeginFramesNotFromClient_SwapThrottled(bool begin_frame_scheduling_enabled,
// BeginImplFrame deadline should draw.
scheduler->SetNeedsRedraw();
client.task_runner().RunPendingTasks(); // Run posted deadline.
- EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 0, 1);
+ EXPECT_ACTION("ScheduledActionAnimate", client, 0, 2);
+ EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client, 1, 2);
EXPECT_FALSE(scheduler->BeginImplFrameDeadlinePending());
EXPECT_FALSE(client.needs_begin_frame());
client.Reset();
diff --git a/cc/test/fake_layer_tree_host_impl_client.h b/cc/test/fake_layer_tree_host_impl_client.h
index 57350bf..3944bf7 100644
--- a/cc/test/fake_layer_tree_host_impl_client.h
+++ b/cc/test/fake_layer_tree_host_impl_client.h
@@ -27,6 +27,7 @@ class FakeLayerTreeHostImplClient : public LayerTreeHostImplClient {
virtual void SetNeedsRedrawOnImplThread() OVERRIDE {}
virtual void SetNeedsRedrawRectOnImplThread(
const gfx::Rect& damage_rect) OVERRIDE {}
+ virtual void SetNeedsAnimateOnImplThread() OVERRIDE {}
virtual void DidInitializeVisibleTileOnImplThread() OVERRIDE {}
virtual void SetNeedsCommitOnImplThread() OVERRIDE {}
virtual void SetNeedsManageTilesOnImplThread() OVERRIDE {}
diff --git a/cc/trees/layer_tree_host_impl.cc b/cc/trees/layer_tree_host_impl.cc
index 108969d..e764517 100644
--- a/cc/trees/layer_tree_host_impl.cc
+++ b/cc/trees/layer_tree_host_impl.cc
@@ -470,15 +470,11 @@ void LayerTreeHostImpl::StartPageScaleAnimation(
duration.InSecondsF());
}
- SetNeedsRedraw();
+ SetNeedsAnimate();
client_->SetNeedsCommitOnImplThread();
client_->RenewTreePriority();
}
-void LayerTreeHostImpl::ScheduleAnimation() {
- SetNeedsRedraw();
-}
-
bool LayerTreeHostImpl::HaveTouchEventHandlersAt(
const gfx::Point& viewport_point) {
if (!settings_.touch_hit_testing)
@@ -1719,6 +1715,11 @@ void LayerTreeHostImpl::SetVisible(bool visible) {
renderer_->SetVisible(visible);
}
+void LayerTreeHostImpl::SetNeedsAnimate() {
+ NotifySwapPromiseMonitorsOfSetNeedsRedraw();
+ client_->SetNeedsAnimateOnImplThread();
+}
+
void LayerTreeHostImpl::SetNeedsRedraw() {
NotifySwapPromiseMonitorsOfSetNeedsRedraw();
client_->SetNeedsRedrawOnImplThread();
@@ -2714,6 +2715,8 @@ void LayerTreeHostImpl::AnimatePageScale(base::TimeTicks monotonic_time) {
page_scale_animation_.reset();
client_->SetNeedsCommitOnImplThread();
client_->RenewTreePriority();
+ } else {
+ SetNeedsAnimate();
}
}
@@ -2723,14 +2726,12 @@ void LayerTreeHostImpl::AnimateTopControls(base::TimeTicks time) {
gfx::Vector2dF scroll = top_controls_manager_->Animate(time);
if (active_tree_->TotalScrollOffset().y() == 0.f)
return;
- if (scroll.IsZero()) {
- // This may happen on the first animation step. Force redraw otherwise
- // the animation would stop because of no new frames.
- SetNeedsRedraw();
- } else {
+ if (!scroll.IsZero()) {
ScrollViewportBy(gfx::ScaleVector2d(
scroll, 1.f / active_tree_->total_page_scale_factor()));
+ SetNeedsRedraw();
}
+ SetNeedsAnimate();
}
void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time) {
@@ -2752,7 +2753,7 @@ void LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time) {
++iter)
(*iter).second->Animate(monotonic_time_for_cc_animations);
- SetNeedsRedraw();
+ SetNeedsAnimate();
}
void LayerTreeHostImpl::UpdateAnimationState(bool start_ready_animations) {
@@ -2774,6 +2775,8 @@ void LayerTreeHostImpl::UpdateAnimationState(bool start_ready_animations) {
if (!events->empty()) {
client_->PostAnimationEventsToMainThreadOnImplThread(events.Pass());
}
+
+ SetNeedsAnimate();
}
base::TimeDelta LayerTreeHostImpl::LowFrequencyAnimationInterval() const {
@@ -2847,9 +2850,10 @@ void LayerTreeHostImpl::AnimateScrollbarsRecursive(LayerImpl* layer,
layer->scrollbar_animation_controller();
if (scrollbar_controller && scrollbar_controller->Animate(time)) {
TRACE_EVENT_INSTANT0(
- "cc", "LayerTreeHostImpl::SetNeedsRedraw due to AnimateScrollbars",
+ "cc",
+ "LayerTreeHostImpl::SetNeedsAnimate due to AnimateScrollbars",
TRACE_EVENT_SCOPE_THREAD);
- SetNeedsRedraw();
+ SetNeedsAnimate();
}
for (size_t i = 0; i < layer->children().size(); ++i)
@@ -2870,10 +2874,11 @@ void LayerTreeHostImpl::StartScrollbarAnimationRecursive(LayerImpl* layer,
layer->scrollbar_animation_controller();
if (scrollbar_controller && scrollbar_controller->IsAnimating()) {
base::TimeDelta delay = scrollbar_controller->DelayBeforeStart(time);
- if (delay > base::TimeDelta())
+ if (delay > base::TimeDelta()) {
client_->RequestScrollbarAnimationOnImplThread(delay);
- else if (scrollbar_controller->Animate(time))
- SetNeedsRedraw();
+ } else if (scrollbar_controller->Animate(time)) {
+ SetNeedsAnimate();
+ }
}
for (size_t i = 0; i < layer->children().size(); ++i)
diff --git a/cc/trees/layer_tree_host_impl.h b/cc/trees/layer_tree_host_impl.h
index 84e7ccd..8eb77fe 100644
--- a/cc/trees/layer_tree_host_impl.h
+++ b/cc/trees/layer_tree_host_impl.h
@@ -72,10 +72,12 @@ class LayerTreeHostImplClient {
virtual void BeginFrame(const BeginFrameArgs& args) = 0;
virtual void OnCanDrawStateChanged(bool can_draw) = 0;
virtual void NotifyReadyToActivate() = 0;
- // Please call these 2 functions through
- // LayerTreeHostImpl's SetNeedsRedraw() and SetNeedsRedrawRect().
+ // Please call these 3 functions through
+ // LayerTreeHostImpl's SetNeedsRedraw(), SetNeedsRedrawRect() and
+ // SetNeedsAnimate().
virtual void SetNeedsRedrawOnImplThread() = 0;
virtual void SetNeedsRedrawRectOnImplThread(const gfx::Rect& damage_rect) = 0;
+ virtual void SetNeedsAnimateOnImplThread() = 0;
virtual void DidInitializeVisibleTileOnImplThread() = 0;
virtual void SetNeedsCommitOnImplThread() = 0;
virtual void SetNeedsManageTilesOnImplThread() = 0;
@@ -138,7 +140,7 @@ class CC_EXPORT LayerTreeHostImpl
bool anchor_point,
float page_scale,
base::TimeDelta duration) OVERRIDE;
- virtual void ScheduleAnimation() OVERRIDE;
+ virtual void SetNeedsAnimate() OVERRIDE;
virtual bool HaveTouchEventHandlersAt(const gfx::Point& viewport_port)
OVERRIDE;
virtual scoped_ptr<SwapPromiseMonitor> CreateLatencyInfoSwapPromiseMonitor(
diff --git a/cc/trees/layer_tree_host_impl_unittest.cc b/cc/trees/layer_tree_host_impl_unittest.cc
index 0d23d11..3711ca7 100644
--- a/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/cc/trees/layer_tree_host_impl_unittest.cc
@@ -85,6 +85,7 @@ class LayerTreeHostImplTest : public testing::Test,
did_notify_ready_to_activate_(false),
did_request_commit_(false),
did_request_redraw_(false),
+ did_request_animate_(false),
did_request_manage_tiles_(false),
did_upload_visible_tile_(false),
reduce_memory_result_(true),
@@ -131,6 +132,9 @@ class LayerTreeHostImplTest : public testing::Test,
const gfx::Rect& damage_rect) OVERRIDE {
did_request_redraw_ = true;
}
+ virtual void SetNeedsAnimateOnImplThread() OVERRIDE {
+ did_request_animate_ = true;
+ }
virtual void SetNeedsManageTilesOnImplThread() OVERRIDE {
did_request_manage_tiles_ = true;
}
@@ -396,6 +400,7 @@ class LayerTreeHostImplTest : public testing::Test,
bool did_notify_ready_to_activate_;
bool did_request_commit_;
bool did_request_redraw_;
+ bool did_request_animate_;
bool did_request_manage_tiles_;
bool did_upload_visible_tile_;
bool reduce_memory_result_;
@@ -904,6 +909,7 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) {
scroll_layer->FixedContainerSizeDelta());
host_impl_->PinchGestureEnd();
host_impl_->ScrollEnd();
+ EXPECT_FALSE(did_request_animate_);
EXPECT_TRUE(did_request_redraw_);
EXPECT_TRUE(did_request_commit_);
EXPECT_EQ(gfx::Size(50, 50), container_layer->bounds());
@@ -970,6 +976,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
host_impl_->PinchGestureEnd();
host_impl_->ScrollEnd();
+ EXPECT_FALSE(did_request_animate_);
EXPECT_TRUE(did_request_redraw_);
EXPECT_TRUE(did_request_commit_);
@@ -1111,19 +1118,30 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) {
max_page_scale);
scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50));
+ did_request_redraw_ = false;
+ did_request_animate_ = false;
host_impl_->StartPageScaleAnimation(gfx::Vector2d(), false, 2.f, duration);
+ EXPECT_FALSE(did_request_redraw_);
+ EXPECT_TRUE(did_request_animate_);
+
did_request_redraw_ = false;
+ did_request_animate_ = false;
host_impl_->Animate(start_time);
EXPECT_TRUE(did_request_redraw_);
+ EXPECT_TRUE(did_request_animate_);
did_request_redraw_ = false;
+ did_request_animate_ = false;
host_impl_->Animate(halfway_through_animation);
EXPECT_TRUE(did_request_redraw_);
+ EXPECT_TRUE(did_request_animate_);
did_request_redraw_ = false;
+ did_request_animate_ = false;
did_request_commit_ = false;
host_impl_->Animate(end_time);
EXPECT_TRUE(did_request_commit_);
+ EXPECT_FALSE(did_request_animate_);
scoped_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
@@ -1138,16 +1156,25 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) {
max_page_scale);
scroll_layer->SetScrollOffset(gfx::Vector2d(50, 50));
+ did_request_redraw_ = false;
+ did_request_animate_ = false;
host_impl_->StartPageScaleAnimation(
gfx::Vector2d(25, 25), true, min_page_scale, duration);
+ EXPECT_FALSE(did_request_redraw_);
+ EXPECT_TRUE(did_request_animate_);
+
did_request_redraw_ = false;
+ did_request_animate_ = false;
host_impl_->Animate(start_time);
EXPECT_TRUE(did_request_redraw_);
+ EXPECT_TRUE(did_request_animate_);
did_request_redraw_ = false;
did_request_commit_ = false;
+ did_request_animate_ = false;
host_impl_->Animate(end_time);
EXPECT_TRUE(did_request_redraw_);
+ EXPECT_FALSE(did_request_animate_);
EXPECT_TRUE(did_request_commit_);
scoped_ptr<ScrollAndScaleSet> scroll_info =
@@ -1301,10 +1328,12 @@ TEST_F(LayerTreeHostImplTest, ScrollbarLinearFadeScheduling) {
host_impl_->ScrollBy(gfx::Point(), gfx::Vector2dF(5, 0));
host_impl_->ScrollEnd();
did_request_redraw_ = false;
+ did_request_animate_ = false;
host_impl_->StartScrollbarAnimation();
EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
requested_scrollbar_animation_delay_);
EXPECT_FALSE(did_request_redraw_);
+ EXPECT_FALSE(did_request_animate_);
requested_scrollbar_animation_delay_ = base::TimeDelta();
// After the fade begins, we should start getting redraws instead of a
@@ -1313,8 +1342,8 @@ TEST_F(LayerTreeHostImplTest, ScrollbarLinearFadeScheduling) {
host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
host_impl_->StartScrollbarAnimation();
EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
- EXPECT_TRUE(did_request_redraw_);
- did_request_redraw_ = false;
+ EXPECT_TRUE(did_request_animate_);
+ did_request_animate_ = false;
// If no scroll happened recently, StartScrollbarAnimation should have no
// effect.
@@ -1331,6 +1360,7 @@ TEST_F(LayerTreeHostImplTest, ScrollbarLinearFadeScheduling) {
EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
requested_scrollbar_animation_delay_);
EXPECT_FALSE(did_request_redraw_);
+ EXPECT_FALSE(did_request_animate_);
requested_scrollbar_animation_delay_ = base::TimeDelta();
// None of the above should have called CurrentFrameTimeTicks, so if we call
@@ -1358,7 +1388,7 @@ TEST_F(LayerTreeHostImplTest, ScrollbarFadePinchZoomScrollbars) {
// effect.
host_impl_->StartScrollbarAnimation();
EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
- EXPECT_FALSE(did_request_redraw_);
+ EXPECT_FALSE(did_request_animate_);
// If no scroll happened during a scroll gesture, StartScrollbarAnimation
// should have no effect.
@@ -1366,7 +1396,7 @@ TEST_F(LayerTreeHostImplTest, ScrollbarFadePinchZoomScrollbars) {
host_impl_->ScrollEnd();
host_impl_->StartScrollbarAnimation();
EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
- EXPECT_FALSE(did_request_redraw_);
+ EXPECT_FALSE(did_request_animate_);
// After a scroll, no fade animation should be scheduled.
host_impl_->ScrollBegin(gfx::Point(), InputHandler::Wheel);
@@ -1375,7 +1405,7 @@ TEST_F(LayerTreeHostImplTest, ScrollbarFadePinchZoomScrollbars) {
did_request_redraw_ = false;
host_impl_->StartScrollbarAnimation();
EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
- EXPECT_FALSE(did_request_redraw_);
+ EXPECT_FALSE(did_request_animate_);
requested_scrollbar_animation_delay_ = base::TimeDelta();
// We should not see any draw requests.
@@ -1383,7 +1413,7 @@ TEST_F(LayerTreeHostImplTest, ScrollbarFadePinchZoomScrollbars) {
host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
host_impl_->StartScrollbarAnimation();
EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
- EXPECT_FALSE(did_request_redraw_);
+ EXPECT_FALSE(did_request_animate_);
// Make page scale > min so that subsequent scrolls will trigger fades.
host_impl_->active_tree()->SetPageScaleDelta(1.1f);
@@ -1396,7 +1426,7 @@ TEST_F(LayerTreeHostImplTest, ScrollbarFadePinchZoomScrollbars) {
host_impl_->StartScrollbarAnimation();
EXPECT_LT(base::TimeDelta::FromMilliseconds(19),
requested_scrollbar_animation_delay_);
- EXPECT_FALSE(did_request_redraw_);
+ EXPECT_FALSE(did_request_animate_);
requested_scrollbar_animation_delay_ = base::TimeDelta();
// After the fade begins, we should start getting redraws instead of a
@@ -1405,7 +1435,7 @@ TEST_F(LayerTreeHostImplTest, ScrollbarFadePinchZoomScrollbars) {
host_impl_override_time->SetCurrentPhysicalTimeTicksForTest(fake_now);
host_impl_->StartScrollbarAnimation();
EXPECT_EQ(base::TimeDelta(), requested_scrollbar_animation_delay_);
- EXPECT_TRUE(did_request_redraw_);
+ EXPECT_TRUE(did_request_animate_);
}
void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
diff --git a/cc/trees/layer_tree_host_unittest_animation.cc b/cc/trees/layer_tree_host_unittest_animation.cc
index aeeb4f5..d546e1b 100644
--- a/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/cc/trees/layer_tree_host_unittest_animation.cc
@@ -1244,5 +1244,69 @@ class LayerTreeHostAnimationTestFrozenAnimationTickTime
// Only the non-impl-paint multi-threaded compositor freezes animations.
MULTI_THREAD_NOIMPL_TEST_F(LayerTreeHostAnimationTestFrozenAnimationTickTime);
+class LayerTreeHostAnimationTestAddAnimationAfterAnimating
+ : public LayerTreeHostAnimationTest {
+ public:
+ LayerTreeHostAnimationTestAddAnimationAfterAnimating()
+ : num_swap_buffers_(0) {}
+
+ virtual void SetupTree() OVERRIDE {
+ LayerTreeHostAnimationTest::SetupTree();
+ content_ = Layer::Create();
+ content_->SetBounds(gfx::Size(4, 4));
+ layer_tree_host()->root_layer()->AddChild(content_);
+ }
+
+ virtual void BeginTest() OVERRIDE { PostSetNeedsCommitToMainThread(); }
+
+ virtual void DidCommit() OVERRIDE {
+ switch (layer_tree_host()->source_frame_number()) {
+ case 1:
+ // First frame: add an animation to the root layer.
+ AddAnimatedTransformToLayer(layer_tree_host()->root_layer(), 0.1, 5, 5);
+ break;
+ case 2:
+ // Second frame: add an animation to the content layer. The root layer
+ // animation has caused us to animate already during this frame.
+ AddOpacityTransitionToLayer(content_.get(), 0.1, 5, 5, false);
+ break;
+ }
+ }
+
+ virtual void SwapBuffersOnThread(LayerTreeHostImpl* host_impl,
+ bool result) OVERRIDE {
+ // The third frame is when both animations have started. Check that both
+ // have a valid start time.
+ if (++num_swap_buffers_ == 3) {
+ EndTest();
+ AnimationRegistrar::AnimationControllerMap copy =
+ host_impl->animation_registrar()->active_animation_controllers();
+ EXPECT_EQ(2u, copy.size());
+ for (AnimationRegistrar::AnimationControllerMap::iterator iter =
+ copy.begin();
+ iter != copy.end();
+ ++iter) {
+ int id = ((*iter).second->id());
+ if (id == host_impl->RootLayer()->id()) {
+ Animation* anim = (*iter).second->GetAnimation(Animation::Transform);
+ EXPECT_GT(anim->start_time(), 0);
+ } else if (id == host_impl->RootLayer()->children()[0]->id()) {
+ Animation* anim = (*iter).second->GetAnimation(Animation::Opacity);
+ EXPECT_GT(anim->start_time(), 0);
+ }
+ }
+ }
+ }
+
+ virtual void AfterTest() OVERRIDE {}
+
+ private:
+ scoped_refptr<Layer> content_;
+ int num_swap_buffers_;
+};
+
+SINGLE_AND_MULTI_THREAD_TEST_F(
+ LayerTreeHostAnimationTestAddAnimationAfterAnimating);
+
} // namespace
} // namespace cc
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc
index a70e08f..a920f5a 100644
--- a/cc/trees/single_thread_proxy.cc
+++ b/cc/trees/single_thread_proxy.cc
@@ -267,6 +267,10 @@ void SingleThreadProxy::SetNeedsRedrawOnImplThread() {
client_->ScheduleComposite();
}
+void SingleThreadProxy::SetNeedsAnimateOnImplThread() {
+ SetNeedsRedrawOnImplThread();
+}
+
void SingleThreadProxy::SetNeedsManageTilesOnImplThread() {
// Thread-only/Impl-side-painting-only feature.
NOTREACHED();
diff --git a/cc/trees/single_thread_proxy.h b/cc/trees/single_thread_proxy.h
index e26e031..8f682be 100644
--- a/cc/trees/single_thread_proxy.h
+++ b/cc/trees/single_thread_proxy.h
@@ -67,6 +67,7 @@ class SingleThreadProxy : public Proxy, LayerTreeHostImplClient {
virtual void SetNeedsRedrawOnImplThread() OVERRIDE;
virtual void SetNeedsRedrawRectOnImplThread(
const gfx::Rect& dirty_rect) OVERRIDE;
+ virtual void SetNeedsAnimateOnImplThread() OVERRIDE;
virtual void SetNeedsManageTilesOnImplThread() OVERRIDE;
virtual void DidInitializeVisibleTileOnImplThread() OVERRIDE;
virtual void SetNeedsCommitOnImplThread() OVERRIDE;
diff --git a/cc/trees/thread_proxy.cc b/cc/trees/thread_proxy.cc
index 97a0c94..9c97ef6 100644
--- a/cc/trees/thread_proxy.cc
+++ b/cc/trees/thread_proxy.cc
@@ -125,8 +125,10 @@ ThreadProxy::CompositorThreadOnly::CompositorThreadOnly(ThreadProxy* proxy,
inside_draw(false),
input_throttled_until_commit(false),
animations_frozen_until_next_draw(false),
+ did_commit_after_animating(false),
renew_tree_priority_pending(false),
- weak_factory(proxy) {}
+ weak_factory(proxy) {
+}
ThreadProxy::CompositorThreadOnly::~CompositorThreadOnly() {}
@@ -563,6 +565,12 @@ void ThreadProxy::SetNeedsRedrawOnImplThread() {
impl().scheduler->SetNeedsRedraw();
}
+void ThreadProxy::SetNeedsAnimateOnImplThread() {
+ TRACE_EVENT0("cc", "ThreadProxy::SetNeedsAnimateOnImplThread");
+ DCHECK(IsImplThread());
+ impl().scheduler->SetNeedsAnimate();
+}
+
void ThreadProxy::SetNeedsManageTilesOnImplThread() {
DCHECK(IsImplThread());
impl().scheduler->SetNeedsManageTiles();
@@ -1020,6 +1028,18 @@ void ThreadProxy::BeginMainFrameAbortedOnImplThread(bool did_handle) {
impl().scheduler->BeginMainFrameAborted(did_handle);
}
+void ThreadProxy::ScheduledActionAnimate() {
+ TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionAnimate");
+ DCHECK(IsImplThread());
+
+ if (!impl().animations_frozen_until_next_draw) {
+ impl().animation_time =
+ impl().layer_tree_host_impl->CurrentFrameTimeTicks();
+ }
+ impl().layer_tree_host_impl->Animate(impl().animation_time);
+ impl().did_commit_after_animating = false;
+}
+
void ThreadProxy::ScheduledActionCommit() {
TRACE_EVENT0("cc", "ThreadProxy::ScheduledActionCommit");
DCHECK(IsImplThread());
@@ -1032,10 +1052,10 @@ void ThreadProxy::ScheduledActionCommit() {
impl().current_resource_update_controller.reset();
if (impl().animations_frozen_until_next_draw) {
- impl().animation_freeze_time =
- std::max(impl().animation_freeze_time,
- blocked_main().last_monotonic_frame_begin_time);
+ impl().animation_time = std::max(
+ impl().animation_time, blocked_main().last_monotonic_frame_begin_time);
}
+ impl().did_commit_after_animating = true;
blocked_main().main_thread_inside_commit = true;
impl().layer_tree_host_impl->BeginCommit();
@@ -1109,17 +1129,13 @@ DrawSwapReadbackResult ThreadProxy::DrawSwapReadbackInternal(
base::TimeDelta draw_duration_estimate = DrawDurationEstimate();
base::AutoReset<bool> mark_inside(&impl().inside_draw, true);
- // Advance our animations.
- base::TimeTicks monotonic_time;
- if (impl().animations_frozen_until_next_draw)
- monotonic_time = impl().animation_freeze_time;
- else
- monotonic_time = impl().layer_tree_host_impl->CurrentFrameTimeTicks();
+ if (impl().did_commit_after_animating) {
+ impl().layer_tree_host_impl->Animate(impl().animation_time);
+ impl().did_commit_after_animating = false;
+ }
- // TODO(enne): This should probably happen post-animate.
if (impl().layer_tree_host_impl->pending_tree())
impl().layer_tree_host_impl->pending_tree()->UpdateDrawProperties();
- impl().layer_tree_host_impl->Animate(monotonic_time);
// This method is called on a forced draw, regardless of whether we are able
// to produce a frame, as the calling site on main thread is blocked until its
@@ -1173,7 +1189,6 @@ DrawSwapReadbackResult ThreadProxy::DrawSwapReadbackInternal(
// checkerboarding will be displayed when we force a draw. To avoid this,
// we freeze animations until we successfully draw.
impl().animations_frozen_until_next_draw = true;
- impl().animation_freeze_time = monotonic_time;
} else {
DCHECK_NE(DrawSwapReadbackResult::DRAW_SUCCESS, result.draw_result);
}
diff --git a/cc/trees/thread_proxy.h b/cc/trees/thread_proxy.h
index aab7a43..381e2be 100644
--- a/cc/trees/thread_proxy.h
+++ b/cc/trees/thread_proxy.h
@@ -82,11 +82,13 @@ class ThreadProxy : public Proxy,
virtual void DidSwapBuffersCompleteOnImplThread() OVERRIDE;
virtual void OnCanDrawStateChanged(bool can_draw) OVERRIDE;
virtual void NotifyReadyToActivate() OVERRIDE;
- // Please call these 2 functions through
- // LayerTreeHostImpl's SetNeedsRedraw() and SetNeedsRedrawRect().
+ // Please call these 3 functions through
+ // LayerTreeHostImpl's SetNeedsRedraw(), SetNeedsRedrawRect() and
+ // SetNeedsAnimate().
virtual void SetNeedsRedrawOnImplThread() OVERRIDE;
virtual void SetNeedsRedrawRectOnImplThread(const gfx::Rect& dirty_rect)
OVERRIDE;
+ virtual void SetNeedsAnimateOnImplThread() OVERRIDE;
virtual void SetNeedsManageTilesOnImplThread() OVERRIDE;
virtual void DidInitializeVisibleTileOnImplThread() OVERRIDE;
virtual void SetNeedsCommitOnImplThread() OVERRIDE;
@@ -111,6 +113,7 @@ class ThreadProxy : public Proxy,
OVERRIDE;
virtual DrawSwapReadbackResult ScheduledActionDrawAndSwapForced() OVERRIDE;
virtual DrawSwapReadbackResult ScheduledActionDrawAndReadback() OVERRIDE;
+ virtual void ScheduledActionAnimate() OVERRIDE;
virtual void ScheduledActionCommit() OVERRIDE;
virtual void ScheduledActionUpdateVisibleTiles() OVERRIDE;
virtual void ScheduledActionActivatePendingTree() OVERRIDE;
@@ -283,7 +286,11 @@ class ThreadProxy : public Proxy,
// Set when we freeze animations to avoid checkerboarding.
bool animations_frozen_until_next_draw;
- base::TimeTicks animation_freeze_time;
+ base::TimeTicks animation_time;
+
+ // Whether a commit has been completed since the last time animations were
+ // ticked. If this happens, we need to animate again.
+ bool did_commit_after_animating;
base::TimeTicks smoothness_takes_priority_expiration_time;
bool renew_tree_priority_pending;
diff --git a/content/renderer/input/input_handler_proxy.cc b/content/renderer/input/input_handler_proxy.cc
index d7b594d..471abda 100644
--- a/content/renderer/input/input_handler_proxy.cc
+++ b/content/renderer/input/input_handler_proxy.cc
@@ -338,7 +338,7 @@ InputHandlerProxy::HandleGestureFling(
WebPoint(gesture_event.globalX, gesture_event.globalY);
fling_parameters_.modifiers = gesture_event.modifiers;
fling_parameters_.sourceDevice = gesture_event.sourceDevice;
- input_handler_->ScheduleAnimation();
+ input_handler_->SetNeedsAnimate();
return DID_HANDLE;
}
case cc::InputHandler::ScrollUnknown:
@@ -378,7 +378,7 @@ void InputHandlerProxy::Animate(base::TimeTicks time) {
if (!fling_parameters_.startTime ||
monotonic_time_sec <= fling_parameters_.startTime) {
fling_parameters_.startTime = monotonic_time_sec;
- input_handler_->ScheduleAnimation();
+ input_handler_->SetNeedsAnimate();
return;
}
@@ -390,7 +390,7 @@ void InputHandlerProxy::Animate(base::TimeTicks time) {
fling_is_active = false;
if (fling_is_active) {
- input_handler_->ScheduleAnimation();
+ input_handler_->SetNeedsAnimate();
} else {
TRACE_EVENT_INSTANT0("input",
"InputHandlerProxy::animate::flingOver",
diff --git a/content/renderer/input/input_handler_proxy_unittest.cc b/content/renderer/input/input_handler_proxy_unittest.cc
index 48f98fe..5cd8a83 100644
--- a/content/renderer/input/input_handler_proxy_unittest.cc
+++ b/content/renderer/input/input_handler_proxy_unittest.cc
@@ -43,7 +43,7 @@ class MockInputHandler : public cc::InputHandler {
void(float magnify_delta, const gfx::Point& anchor));
MOCK_METHOD0(PinchGestureEnd, void());
- MOCK_METHOD0(ScheduleAnimation, void());
+ MOCK_METHOD0(SetNeedsAnimate, void());
MOCK_METHOD2(ScrollBegin,
ScrollStatus(const gfx::Point& viewport_point,
@@ -405,7 +405,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingStartedTouchpad) {
EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
EXPECT_CALL(mock_input_handler_, ScrollEnd());
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
gesture_.type = WebInputEvent::GestureFlingStart;
gesture_.data.flingStart.velocityX = 10;
@@ -488,7 +488,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingAnimatesTouchpad) {
gesture_.globalX = fling_global_point.x;
gesture_.globalY = fling_global_point.y;
gesture_.modifiers = modifiers;
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
EXPECT_CALL(mock_input_handler_, ScrollEnd());
@@ -500,7 +500,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingAnimatesTouchpad) {
// fling start will typically include the last scroll from the gesture that
// lead to the scroll (either wheel or gesture scroll), so there should be no
// visible hitch.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
.Times(0);
base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
@@ -509,7 +509,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingAnimatesTouchpad) {
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
// The second call should start scrolling in the -X direction.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
EXPECT_CALL(mock_input_handler_,
@@ -562,7 +562,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingAnimatesTouchpad) {
// Since we've aborted the fling, the next animation should be a no-op and
// should not result in another
// frame being requested.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation()).Times(0);
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()).Times(0);
EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
.Times(0);
time += base::TimeDelta::FromMilliseconds(100);
@@ -597,7 +597,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) {
gesture_.globalX = fling_global_point.x;
gesture_.globalY = fling_global_point.y;
gesture_.modifiers = modifiers;
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
EXPECT_CALL(mock_input_handler_, ScrollEnd());
@@ -607,7 +607,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) {
// Start the fling animation at time 10. This shouldn't actually scroll, just
// establish a start time.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
.Times(0);
base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
@@ -616,7 +616,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) {
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
// The second call should start scrolling in the -X direction.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
EXPECT_CALL(mock_input_handler_,
@@ -670,7 +670,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) {
// Since we've aborted the fling, the next animation should be a no-op and
// should not result in another
// frame being requested.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation()).Times(0);
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()).Times(0);
EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
.Times(0);
time += base::TimeDelta::FromMilliseconds(100);
@@ -702,7 +702,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) {
gesture_.globalX = fling_global_point.x;
gesture_.globalY = fling_global_point.y;
gesture_.modifiers = modifiers;
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
EXPECT_CALL(mock_input_handler_, ScrollEnd());
@@ -712,7 +712,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) {
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
// Start the second fling animation at time 30.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
.Times(0);
time = base::TimeTicks() + base::TimeDelta::FromSeconds(30);
@@ -721,7 +721,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingTransferResetsTouchpad) {
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
// Tick the second fling once normally.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
EXPECT_CALL(mock_input_handler_,
@@ -776,7 +776,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingStartedTouchscreen) {
EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
gesture_.type = WebInputEvent::GestureFlingStart;
gesture_.data.flingStart.velocityX = 10;
@@ -881,7 +881,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingAnimatesTouchscreen) {
gesture_.globalX = fling_global_point.x;
gesture_.globalY = fling_global_point.y;
gesture_.modifiers = modifiers;
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
@@ -892,14 +892,14 @@ TEST_F(InputHandlerProxyTest, GestureFlingAnimatesTouchscreen) {
// fling start will typically include the last scroll from the gesture that
// lead to the scroll (either wheel or gesture scroll), so there should be no
// visible hitch.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
input_handler_->Animate(time);
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
// The second call should start scrolling in the -X direction.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_,
ScrollBy(testing::_,
testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
@@ -945,7 +945,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingWithValidTimestamp) {
gesture_.globalX = fling_global_point.x;
gesture_.globalY = fling_global_point.y;
gesture_.modifiers = modifiers;
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
@@ -956,7 +956,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingWithValidTimestamp) {
// the likelihood of a hitch between the scroll preceding the fling and
// the first scroll generated by the fling.
// Scrolling should start in the -X direction.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_,
ScrollBy(testing::_,
testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
@@ -1005,7 +1005,7 @@ TEST_F(InputHandlerProxyTest,
gesture_.globalX = fling_global_point.x;
gesture_.globalY = fling_global_point.y;
gesture_.modifiers = modifiers;
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
@@ -1020,14 +1020,14 @@ TEST_F(InputHandlerProxyTest,
// fling start will typically include the last scroll from the gesture that
// lead to the scroll (either wheel or gesture scroll), so there should be no
// visible hitch.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
input_handler_->Animate(time);
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
// The second call should start scrolling in the -X direction.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_,
ScrollBy(testing::_,
testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
@@ -1057,7 +1057,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingStopsAtContentEdge) {
WebFloatPoint fling_delta = WebFloatPoint(1000, 1000);
gesture_.data.flingStart.velocityX = fling_delta.x;
gesture_.data.flingStart.velocityY = fling_delta.y;
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
EXPECT_CALL(mock_input_handler_, ScrollEnd());
@@ -1065,13 +1065,13 @@ TEST_F(InputHandlerProxyTest, GestureFlingStopsAtContentEdge) {
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
// The first animate doesn't cause any scrolling.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
input_handler_->Animate(time);
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
// The second animate starts scrolling in the positive X and Y directions.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
EXPECT_CALL(mock_input_handler_,
@@ -1099,7 +1099,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingStopsAtContentEdge) {
latest_overscroll_delta);
// The next call to animate will no longer scroll vertically.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_, ScrollBegin(testing::_, testing::_))
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
EXPECT_CALL(mock_input_handler_,
@@ -1144,7 +1144,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingNotCancelledBySmallTimeDelta) {
gesture_.globalX = fling_global_point.x;
gesture_.globalY = fling_global_point.y;
gesture_.modifiers = modifiers;
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
@@ -1152,7 +1152,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingNotCancelledBySmallTimeDelta) {
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
// With an animation timestamp equivalent to the starting timestamp, the
// animation will simply be rescheduled.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
input_handler_->Animate(time);
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
@@ -1160,7 +1160,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingNotCancelledBySmallTimeDelta) {
// A small time delta should not stop the fling, even if the client
// reports no scrolling.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_,
ScrollBy(testing::_,
testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))
@@ -1173,7 +1173,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingNotCancelledBySmallTimeDelta) {
// A time delta of zero should not stop the fling, and neither should it
// trigger scrolling on the client.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
input_handler_->Animate(time);
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
@@ -1213,18 +1213,18 @@ TEST_F(InputHandlerProxyTest, GestureFlingCancelledAfterBothAxesStopScrolling) {
gesture_.data.flingStart.velocityY = fling_delta.y;
EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
// The first animate doesn't cause any scrolling.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
base::TimeTicks time = base::TimeTicks() + base::TimeDelta::FromSeconds(10);
input_handler_->Animate(time);
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
// The second animate starts scrolling in the positive X and Y directions.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_,
ScrollBy(testing::_,
testing::Property(&gfx::Vector2dF::y, testing::Lt(0))))
@@ -1249,7 +1249,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingCancelledAfterBothAxesStopScrolling) {
latest_overscroll_delta);
// The next call to animate will no longer scroll vertically.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_,
ScrollBy(testing::_,
testing::Property(&gfx::Vector2dF::y, testing::Eq(0))))
@@ -1274,7 +1274,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingCancelledAfterBothAxesStopScrolling) {
latest_overscroll_delta);
// The next call to animate will no longer scroll horizontally or vertically,
// and the fling should be cancelled.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation()).Times(0);
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate()).Times(0);
EXPECT_CALL(mock_input_handler_, ScrollBy(testing::_, testing::_)).Times(0);
EXPECT_CALL(mock_input_handler_, ScrollEnd());
time += base::TimeDelta::FromMilliseconds(10);
@@ -1363,7 +1363,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingCancelledByKeyboardEvent) {
gesture_.data.flingStart.velocityY = fling_delta.y;
EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
EXPECT_TRUE(input_handler_->gesture_scroll_on_impl_thread_for_testing());
testing::Mock::VerifyAndClearExpectations(&mock_input_handler_);
@@ -1418,7 +1418,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingWithNegativeTimeDelta) {
gesture_.globalX = fling_global_point.x;
gesture_.globalY = fling_global_point.y;
gesture_.modifiers = modifiers;
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_, FlingScrollBegin())
.WillOnce(testing::Return(cc::InputHandler::ScrollStarted));
EXPECT_EQ(expected_disposition_, input_handler_->HandleInputEvent(gesture_));
@@ -1428,7 +1428,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingWithNegativeTimeDelta) {
// If we get a negative time delta, that is, the Animation tick time happens
// before the fling's start time then we should *not* try scrolling and
// instead reset the fling start time.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_,
ScrollBy(testing::_,
testing::_)).Times(0);
@@ -1440,7 +1440,7 @@ TEST_F(InputHandlerProxyTest, GestureFlingWithNegativeTimeDelta) {
// The first call should have reset the start time so subsequent calls should
// generate scroll events.
- EXPECT_CALL(mock_input_handler_, ScheduleAnimation());
+ EXPECT_CALL(mock_input_handler_, SetNeedsAnimate());
EXPECT_CALL(mock_input_handler_,
ScrollBy(testing::_,
testing::Property(&gfx::Vector2dF::x, testing::Lt(0))))