summaryrefslogtreecommitdiffstats
path: root/cc/scheduler
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-06 00:35:18 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-06 00:35:18 +0000
commit3d9f74315b09318f7459f6654c2eac21dc46cff8 (patch)
tree01082af9bd757db78a0185e8b0b96090fc7e5bb3 /cc/scheduler
parent13ba1daed34f6e54cc159b56dbc6f16afafae303 (diff)
downloadchromium_src-3d9f74315b09318f7459f6654c2eac21dc46cff8.zip
chromium_src-3d9f74315b09318f7459f6654c2eac21dc46cff8.tar.gz
chromium_src-3d9f74315b09318f7459f6654c2eac21dc46cff8.tar.bz2
cc: Make animations tick regardless of drawing.
The compositor should tick and finish animations even if it is not drawing anything. It can not draw for various reasons: 1) The tab is backgrounded. 2) CanDraw() is false for any of its reasons. 3) PrepareToDraw() fails due to checkerboarding. 4) There is no damage on the screen to draw. Currently the problems are: - When backgrounded, the animations are ticked but their states are not updated. - When CanDraw() is false, we don't draw, and animations just stop ticking. - If we stop drawing when we damage the screen, we tick animations, but don't update animation state since this happens in DrawLayers(). To solve these problems, I've moved the animation control more explicitly out of LayerTreeHostImpl. The proxy already calls Animate(). Now it will also call UpdateAnimationState(). It always does this after calling Animate() regardless if drawing or not. Secondly, the missing UpdateAnimationState() call is added to the OnTimerTick for background animation ticking. We enable background ticking only when we change visibility, currently. But when CanDraw() is false, we don't draw and thus don't tick animations. So instead we add to LayerTreeHostImpl a UpdateBackgroundAnimateTicking() method. We call this always after calling Animate() since that can remove animations - it's something Animate() used to do. And we also call this: a) After a commit - this could add new animations, or change visibility. b) After changing CanDraw()'s state. However, when PrepareToDraw() is false, we do not want to start new animations so we let animations finish without starting new ones. This is verified by the LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations test. This is covered by adding single-thread mode to all the animation unit tests (except those that call SetNeedsAnimate() which is not legal in single thread mode). Also by new tests: LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw.RunSingleThread LayerTreeHostAnimationTestRunAnimationWhenNotCanDraw.RunMultiThread LayerTreeHostAnimationTestRunAnimationWhenNotVisible.RunSingleThread LayerTreeHostAnimationTestRunAnimationWhenNotVisible.RunMultiThread LayerTreeHostAnimationTestCheckerboardDoesntStartAnimations.RunMultiThread Added scheduler tests: SchedulerStateMachineTest.ReportIfNotDrawing SchedulerStateMachineTest.ReportIfNotDrawingFromAcquiredTextures R=ajuma@chromium.org BUG=222915 Review URL: https://chromiumcodereview.appspot.com/13613003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@192671 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/scheduler')
-rw-r--r--cc/scheduler/scheduler.cc4
-rw-r--r--cc/scheduler/scheduler.h2
-rw-r--r--cc/scheduler/scheduler_state_machine.h5
-rw-r--r--cc/scheduler/scheduler_state_machine_unittest.cc56
4 files changed, 66 insertions, 1 deletions
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc
index c1da5f2..b088a0f 100644
--- a/cc/scheduler/scheduler.cc
+++ b/cc/scheduler/scheduler.cc
@@ -199,4 +199,8 @@ void Scheduler::ProcessScheduledActions() {
client_->DidAnticipatedDrawTimeChange(frame_rate_controller_->NextTickTime());
}
+bool Scheduler::WillDrawIfNeeded() const {
+ return !state_machine_.DrawSuspendedUntilCommit();
+}
+
} // namespace cc
diff --git a/cc/scheduler/scheduler.h b/cc/scheduler/scheduler.h
index ea23e22..08da4ad 100644
--- a/cc/scheduler/scheduler.h
+++ b/cc/scheduler/scheduler.h
@@ -96,6 +96,8 @@ class CC_EXPORT Scheduler : FrameRateControllerClient {
bool CommitPending() const { return state_machine_.CommitPending(); }
bool RedrawPending() const { return state_machine_.RedrawPending(); }
+ bool WillDrawIfNeeded() const;
+
void SetTimebaseAndInterval(base::TimeTicks timebase,
base::TimeDelta interval);
diff --git a/cc/scheduler/scheduler_state_machine.h b/cc/scheduler/scheduler_state_machine.h
index 4c342af..55581a4 100644
--- a/cc/scheduler/scheduler_state_machine.h
+++ b/cc/scheduler/scheduler_state_machine.h
@@ -144,11 +144,14 @@ class CC_EXPORT SchedulerStateMachine {
// Exposed for testing purposes.
void SetMaximumNumberOfFailedDrawsBeforeDrawIsForced(int num_draws);
+ // False if drawing is not being prevented, true if drawing won't happen
+ // for some reason, such as not being visible.
+ bool DrawSuspendedUntilCommit() const;
+
std::string ToString();
protected:
bool ShouldDrawForced() const;
- bool DrawSuspendedUntilCommit() const;
bool ScheduledToDraw() const;
bool ShouldDraw() const;
bool ShouldAttemptTreeActivation() const;
diff --git a/cc/scheduler/scheduler_state_machine_unittest.cc b/cc/scheduler/scheduler_state_machine_unittest.cc
index 93fc82f..6111b76 100644
--- a/cc/scheduler/scheduler_state_machine_unittest.cc
+++ b/cc/scheduler/scheduler_state_machine_unittest.cc
@@ -1077,5 +1077,61 @@ TEST(SchedulerStateMachineTest, ImmediateBeginFrameWhileCantDraw) {
state.DidLeaveVSync();
}
+TEST(SchedulerStateMachineTest, ReportIfNotDrawing) {
+ SchedulerSettings default_scheduler_settings;
+ SchedulerStateMachine state(default_scheduler_settings);
+
+ state.SetCanDraw(true);
+ state.SetVisible(true);
+ EXPECT_FALSE(state.DrawSuspendedUntilCommit());
+
+ state.SetCanDraw(false);
+ state.SetVisible(true);
+ EXPECT_TRUE(state.DrawSuspendedUntilCommit());
+
+ state.SetCanDraw(true);
+ state.SetVisible(false);
+ EXPECT_TRUE(state.DrawSuspendedUntilCommit());
+
+ state.SetCanDraw(false);
+ state.SetVisible(false);
+ EXPECT_TRUE(state.DrawSuspendedUntilCommit());
+
+ state.SetCanDraw(true);
+ state.SetVisible(true);
+ EXPECT_FALSE(state.DrawSuspendedUntilCommit());
+}
+
+TEST(SchedulerStateMachineTest, ReportIfNotDrawingFromAcquiredTextures) {
+ SchedulerSettings default_scheduler_settings;
+ SchedulerStateMachine state(default_scheduler_settings);
+ state.SetCanBeginFrame(true);
+ state.SetCanDraw(true);
+ state.SetVisible(true);
+ EXPECT_FALSE(state.DrawSuspendedUntilCommit());
+
+ state.SetMainThreadNeedsLayerTextures();
+ EXPECT_EQ(
+ SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD,
+ state.NextAction());
+ state.UpdateState(state.NextAction());
+ EXPECT_TRUE(state.DrawSuspendedUntilCommit());
+
+ EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.NextAction());
+
+ state.UpdateState(state.NextAction());
+ EXPECT_TRUE(state.DrawSuspendedUntilCommit());
+
+ EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+
+ state.BeginFrameComplete();
+ EXPECT_TRUE(state.DrawSuspendedUntilCommit());
+
+ EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
+
+ state.UpdateState(state.NextAction());
+ EXPECT_FALSE(state.DrawSuspendedUntilCommit());
+}
+
} // namespace
} // namespace cc