summaryrefslogtreecommitdiffstats
path: root/cc/scheduler/scheduler_state_machine_unittest.cc
diff options
context:
space:
mode:
authorenne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-30 07:17:50 +0000
committerenne@chromium.org <enne@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-07-30 07:17:50 +0000
commit3519b87a40f8f49c270869f2c2df6e1ec4ada8da (patch)
treeefcdc25e20f68e6b60836659be002846d2599c8c /cc/scheduler/scheduler_state_machine_unittest.cc
parent798a1b069246a628ed772a60598d5f2ad4a13ce9 (diff)
downloadchromium_src-3519b87a40f8f49c270869f2c2df6e1ec4ada8da.zip
chromium_src-3519b87a40f8f49c270869f2c2df6e1ec4ada8da.tar.gz
chromium_src-3519b87a40f8f49c270869f2c2df6e1ec4ada8da.tar.bz2
cc: Allow the main thread to cancel commits
Add a new SetNeedsUpdateLayers that triggers the commit flow, but is abortable if update layers doesn't actually make any changes. This allows the main thread to abort a begin frame. This happens in the case of scroll updates from the compositor thread or invalidations. There was previously an abort begin frame call for when a visibility message and a begin frame message were posted simultaneously, but it incorrectly applied the scrolls and scales without informing the compositor thread that these had already been consumed. To fix this, the abort message passes back a boolean about whether or not the commit was aborted (and needed to be sent again) or was handled (and the scrolls and scales processed). To avoid a deluge of begin frames (in the commit sense) from the scheduler, the scheduler has been adjusted to wait until the next begin frame (in the vsync signal sense) so that these calls can be throttled. Otherwise, the scheduler will just keep trying to begin frame. R=brianderson@chromium.org, danakj@chromium.org BUG=256381 Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=213338 Review URL: https://chromiumcodereview.appspot.com/19106007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@214314 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc/scheduler/scheduler_state_machine_unittest.cc')
-rw-r--r--cc/scheduler/scheduler_state_machine_unittest.cc100
1 files changed, 96 insertions, 4 deletions
diff --git a/cc/scheduler/scheduler_state_machine_unittest.cc b/cc/scheduler/scheduler_state_machine_unittest.cc
index 7036459..c7210eb 100644
--- a/cc/scheduler/scheduler_state_machine_unittest.cc
+++ b/cc/scheduler/scheduler_state_machine_unittest.cc
@@ -718,7 +718,7 @@ TEST(SchedulerStateMachineTest, TestGoesInvisibleBeforeFinishCommit) {
// Become invisible and abort the main thread's begin frame.
state.SetVisible(false);
- state.BeginFrameAbortedByMainThread();
+ state.BeginFrameAbortedByMainThread(false);
// We should now be back in the idle state as if we didn't start a frame at
// all.
@@ -728,8 +728,14 @@ TEST(SchedulerStateMachineTest, TestGoesInvisibleBeforeFinishCommit) {
// Become visible again.
state.SetVisible(true);
- // We should be beginning a frame now.
+ // Although we have aborted on this frame and haven't cancelled the commit
+ // (i.e. need another), don't send another begin frame yet.
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
+ EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_TRUE(state.NeedsCommit());
+
+ // Start a new frame.
+ state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD,
state.NextAction());
@@ -741,6 +747,52 @@ TEST(SchedulerStateMachineTest, TestGoesInvisibleBeforeFinishCommit) {
state.CommitState());
}
+TEST(SchedulerStateMachineTest, AbortBeginFrameAndCancelCommit) {
+ SchedulerSettings default_scheduler_settings;
+ StateMachine state(default_scheduler_settings);
+ state.SetCanStart();
+ state.UpdateState(state.NextAction());
+ state.DidCreateAndInitializeOutputSurface();
+ state.SetVisible(true);
+ state.SetCanDraw(true);
+
+ // Get into a begin frame / commit state.
+ state.SetNeedsCommit();
+ EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD,
+ state.NextAction());
+ state.UpdateState(
+ SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD);
+ EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS,
+ state.CommitState());
+ EXPECT_FALSE(state.NeedsCommit());
+ EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+
+ // Abort the commit, cancelling future commits.
+ state.BeginFrameAbortedByMainThread(true);
+
+ // Verify that another commit doesn't start on the same frame.
+ EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
+ EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_FALSE(state.NeedsCommit());
+
+ // Start a new frame; draw because this is the first frame since output
+ // surface init'd.
+ state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction());
+ state.DidLeaveBeginFrame();
+
+ // Verify another commit doesn't start on another frame either.
+ EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
+ EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_FALSE(state.NeedsCommit());
+
+ // Verify another commit can start if requested, though.
+ state.SetNeedsCommit();
+ EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
+ EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD,
+ state.NextAction());
+}
+
TEST(SchedulerStateMachineTest, TestFirstContextCreation) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
@@ -816,15 +868,23 @@ TEST(SchedulerStateMachineTest,
// Recreate the context
state.DidCreateAndInitializeOutputSurface();
+ EXPECT_FALSE(state.RedrawPending());
// When the context is recreated, we should begin a commit
EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD,
state.NextAction());
state.UpdateState(state.NextAction());
+ EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS,
+ state.CommitState());
+ state.FinishCommit();
+ EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
+ state.UpdateState(state.NextAction());
+ // Finishing the first commit after initializing an output surface should
+ // automatically cause a redraw.
+ EXPECT_TRUE(state.RedrawPending());
// Once the context is recreated, whether we draw should be based on
// SetCanDraw.
- state.SetNeedsRedraw(true);
state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction());
state.SetCanDraw(false);
@@ -1192,7 +1252,7 @@ TEST(SchedulerStateMachineTest,
// Become invisible and abort the main thread's begin frame.
state.SetVisible(false);
- state.BeginFrameAbortedByMainThread();
+ state.BeginFrameAbortedByMainThread(false);
// Should be back in the idle state, but needing a commit.
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
@@ -1295,5 +1355,37 @@ TEST(SchedulerStateMachineTest, ReportIfNotDrawingFromAcquiredTextures) {
EXPECT_FALSE(state.DrawSuspendedUntilCommit());
}
+TEST(SchedulerStateMachineTest, AcquireTexturesWithAbort) {
+ SchedulerSettings default_scheduler_settings;
+ SchedulerStateMachine state(default_scheduler_settings);
+ state.SetCanStart();
+ state.UpdateState(state.NextAction());
+ state.DidCreateAndInitializeOutputSurface();
+ state.SetCanDraw(true);
+ state.SetVisible(true);
+
+ 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_NONE, state.NextAction());
+
+ state.SetNeedsCommit();
+ EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD,
+ state.NextAction());
+ state.UpdateState(state.NextAction());
+ EXPECT_TRUE(state.DrawSuspendedUntilCommit());
+
+ EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+
+ state.BeginFrameAbortedByMainThread(true);
+
+ EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
+ EXPECT_FALSE(state.DrawSuspendedUntilCommit());
+}
+
} // namespace
} // namespace cc