return output_surface_state_;
}
+ void SetReadbackState(SynchronousReadbackState rs) { readback_state_ = rs; }
SynchronousReadbackState readback_state() const { return readback_state_; }
bool NeedsCommit() const { return needs_commit_; }
bool PendingActivationsShouldBeForced() const {
return SchedulerStateMachine::PendingActivationsShouldBeForced();
}
+
+ void SetHasPendingTree(bool has_pending_tree) {
+ has_pending_tree_ = has_pending_tree;
+ }
};
TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) {
state.SetNeedsRedraw(false);
state.SetVisible(true);
- EXPECT_FALSE(state.BeginImplFrameNeeded());
+ EXPECT_FALSE(state.BeginFrameNeeded());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- EXPECT_FALSE(state.BeginImplFrameNeeded());
+ EXPECT_FALSE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.SetVisible(true);
state.SetNeedsCommit();
- EXPECT_FALSE(state.BeginImplFrameNeeded());
+ EXPECT_FALSE(state.BeginFrameNeeded());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- EXPECT_FALSE(state.BeginImplFrameNeeded());
+ EXPECT_FALSE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
state.SetVisible(true);
state.SetNeedsCommit();
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
state.SetCanDraw(true);
state.SetNeedsCommit();
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
// Commit to the pending tree.
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+ // Make sure that a draw of the active tree doesn't spuriously advance
+ // the commit state and unblock the next commit.
+ state.SetNeedsRedraw(true);
+ 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);
+ EXPECT_EQ(state.CommitState(),
+ SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
+ EXPECT_TRUE(state.has_pending_tree());
+
// Verify NotifyReadyToActivate unblocks activation, draw, and
// commit in that order.
+ state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_EQ(state.CommitState(),
SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
state.SetCanDraw(true);
state.SetNeedsCommit();
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
// Commit to the pending tree.
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
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);
state.SetCanDraw(true);
state.SetNeedsRedraw(true);
EXPECT_TRUE(state.RedrawPending());
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
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());
state.SetCanDraw(true);
state.SetNeedsRedraw(true);
EXPECT_TRUE(state.RedrawPending());
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ 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(
state.SetCanDraw(true);
state.SetNeedsRedraw(true);
EXPECT_TRUE(state.RedrawPending());
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
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());
// 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);
state.DidDrawIfPossibleCompleted(
DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
EXPECT_TRUE(state.RedrawPending());
// But the commit is ongoing.
EXPECT_TRUE(state.CommitPending());
// 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);
// 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);
DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
}
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
EXPECT_TRUE(state.RedrawPending());
// But the commit is ongoing.
EXPECT_TRUE(state.CommitPending());
// Start a draw.
state.SetNeedsRedraw(true);
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ 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());
EXPECT_TRUE(state.RedrawPending());
// We should not be trying to draw again now, but we have a commit pending.
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ 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
state.SetNeedsRedraw(true);
// Draw the first frame.
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ 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(SchedulerStateMachine::ACTION_NONE);
// Move to another frame. This should now draw.
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ 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(SchedulerStateMachine::ACTION_NONE);
// We just swapped, so we should proactively request another BeginImplFrame.
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
}
TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) {
state.SetCommitState(all_commit_states[i]);
state.SetBeginImplFrameState(
SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
+
if (request_readback) {
state.SetNeedsForcedRedrawForReadback();
} else {
} 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.
- EXPECT_NE(state.BeginImplFrameNeeded(), request_readback)
- << *state.AsValue();
+ EXPECT_NE(state.BeginFrameNeeded(), request_readback) << *state.AsValue();
EXPECT_EQ(state.NextAction(), expected_action) << *state.AsValue();
// Case 2: needs_commit=true.
state.SetNeedsCommit();
- EXPECT_NE(state.BeginImplFrameNeeded(), request_readback)
- << *state.AsValue();
+ EXPECT_NE(state.BeginFrameNeeded(), request_readback) << *state.AsValue();
EXPECT_EQ(state.NextAction(), expected_action) << *state.AsValue();
}
}
state.SetVisible(true);
state.SetCanDraw(true);
- EXPECT_TRUE(state.BeginImplFrameNeeded());
+ EXPECT_TRUE(state.BeginFrameNeeded());
// Begin the frame.
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
// 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);
// 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);
// 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);
// 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(
// 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,
// 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);
// 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);
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);
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(
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
}
+void TestForceCommitWhenReplacementActivationInProgress(
+ bool main_frame_before_draw_enabled) {
+ SchedulerSettings settings;
+ settings.impl_side_painting = true;
+ settings.main_frame_before_draw_enabled = main_frame_before_draw_enabled;
+ StateMachine state(settings);
+ state.SetCanStart();
+ state.UpdateState(state.NextAction());
+ state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
+ state.SetVisible(true);
+ state.SetCanDraw(true);
+
+ // Impl-side painting of replacement commit is in-progress.
+ if (settings.main_frame_before_draw_enabled) {
+ state.SetCommitState(
+ SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION);
+ } else {
+ state.SetCommitState(
+ SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
+ }
+ state.SetReadbackState(
+ SchedulerStateMachine::READBACK_STATE_WAITING_FOR_REPLACEMENT_ACTIVATION);
+ state.SetHasPendingTree(true);
+
+ // Forced commit is requested during the impl-side painting.
+ state.SetNeedsForcedCommitForReadback();
+ EXPECT_FALSE(state.NeedsCommit());
+
+ state.NotifyReadyToActivate();
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE);
+ // New replacement commit is needed for incoming forced commit.
+ EXPECT_EQ(SchedulerStateMachine::READBACK_STATE_NEEDS_BEGIN_MAIN_FRAME,
+ state.readback_state());
+ EXPECT_TRUE(state.NeedsCommit());
+ if (settings.main_frame_before_draw_enabled) {
+ // New replacement commit is scheduled.
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
+ // Forced commit is started.
+ EXPECT_EQ(SchedulerStateMachine::READBACK_STATE_WAITING_FOR_COMMIT,
+ state.readback_state());
+ }
+ 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();
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
+ if (!settings.main_frame_before_draw_enabled) {
+ // New replacement commit is scheduled.
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
+ // Forced commit is started.
+ EXPECT_EQ(SchedulerStateMachine::READBACK_STATE_WAITING_FOR_COMMIT,
+ state.readback_state());
+ }
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::ACTION_NONE);
+
+ // Finish the forced commit and draw it.
+ state.NotifyBeginMainFrameStarted();
+ state.NotifyReadyToCommit();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
+ state.NotifyReadyToActivate();
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK)
+ EXPECT_EQ(
+ SchedulerStateMachine::READBACK_STATE_WAITING_FOR_REPLACEMENT_COMMIT,
+ state.readback_state());
+ EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
+ state.CommitState());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+
+ // Finish the replacement commit and draw it.
+ state.NotifyBeginMainFrameStarted();
+ state.NotifyReadyToCommit();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
+ state.NotifyReadyToActivate();
+ 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(
+ SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
+ EXPECT_EQ(SchedulerStateMachine::READBACK_STATE_IDLE, state.readback_state());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+}
+
+// Explicitly test when main_frame_before_draw_enabled = true.
+TEST(SchedulerStateMachineTest,
+ ForceCommitWhenReplacementActivationInProgressAndMainFrameEnabled) {
+ bool main_frame_before_draw_enabled = true;
+ TestForceCommitWhenReplacementActivationInProgress(
+ main_frame_before_draw_enabled);
+}
+
+// Explicitly test when main_frame_before_draw_enabled = false.
+TEST(SchedulerStateMachineTest,
+ ForceCommitWhenReplacementActivationInProgressAndMainFrameDisabled) {
+ bool main_frame_before_draw_enabled = false;
+ TestForceCommitWhenReplacementActivationInProgress(
+ main_frame_before_draw_enabled);
+}
+
+// Test with main_frame_before_activation_enable = true;
+TEST(SchedulerStateMachineTest,
+ ForceCommitWhenReplacementActivationInProgressWithMFBA) {
+ SchedulerSettings settings;
+ settings.impl_side_painting = true;
+ settings.main_frame_before_activation_enabled = true;
+ StateMachine state(settings);
+ state.SetCanStart();
+ state.UpdateState(state.NextAction());
+ state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
+ state.SetVisible(true);
+ state.SetCanDraw(true);
+
+ // When impl-side painting of replacement commit is in-progress, commit state
+ // is idle because main_frame_before_activation is enabled.
+ state.SetCommitState(
+ SchedulerStateMachine::COMMIT_STATE_IDLE);
+ state.SetReadbackState(
+ SchedulerStateMachine::READBACK_STATE_WAITING_FOR_REPLACEMENT_ACTIVATION);
+ state.SetHasPendingTree(true);
+
+ // New commit is requested and scheduled when impl-side painting is in
+ // progress.
+ state.SetNeedsCommit();
+ state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+
+ // Forced commit is requested during the impl-side painting.
+ state.SetNeedsForcedCommitForReadback();
+ EXPECT_FALSE(state.NeedsCommit());
+
+ state.OnBeginImplFrameDeadline();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+
+ state.NotifyReadyToActivate();
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE);
+ // Replacement commit for requested forced commit is already scheduled.
+ EXPECT_EQ(SchedulerStateMachine::READBACK_STATE_WAITING_FOR_COMMIT,
+ state.readback_state());
+ EXPECT_FALSE(state.NeedsCommit());
+ 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();
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
+ EXPECT_ACTION_UPDATE_STATE(
+ SchedulerStateMachine::ACTION_NONE);
+
+ // forced commit is started.
+ state.NotifyBeginMainFrameStarted();
+ state.NotifyReadyToCommit();
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
+}
+
TEST(SchedulerStateMachineTest, TestInitialActionsWhenContextLost) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
}
-TEST(SchedulerStateMachineTest, ReportIfNotDrawingFromAcquiredTextures) {
- SchedulerSettings default_scheduler_settings;
- StateMachine state(default_scheduler_settings);
- state.SetCanStart();
- state.UpdateState(state.NextAction());
- state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
- state.SetCanDraw(true);
- state.SetVisible(true);
- EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
-
- state.SetMainThreadNeedsLayerTextures();
- EXPECT_ACTION_UPDATE_STATE(
- SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD);
- EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
-
- state.SetNeedsCommit();
- state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
- EXPECT_ACTION_UPDATE_STATE(
- SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
- EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
-
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
-
- state.NotifyBeginMainFrameStarted();
- state.NotifyReadyToCommit();
- EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
-
- EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
-
- state.UpdateState(state.NextAction());
- EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
-}
-
-TEST(SchedulerStateMachineTest, AcquireTexturesWithAbort) {
- SchedulerSettings default_scheduler_settings;
- StateMachine 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.PendingDrawsShouldBeAborted());
-
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
-
- state.SetNeedsCommit();
- EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
- state.NextAction());
- state.UpdateState(state.NextAction());
- EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
-
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
-
- state.BeginMainFrameAborted(true);
-
- EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
- EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
-}
-
TEST(SchedulerStateMachineTest, TestTriggerDeadlineEarlyAfterAbortedCommit) {
SchedulerSettings settings;
settings.impl_side_painting = true;
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);
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);
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