This source file includes following definitions.
- CreateAndInitializeOutputSurfaceWithActivatedCommit
- SetCommitState
- ForcedRedrawState
- SetBeginImplFrameState
- begin_impl_frame_state
- output_surface_state
- SetReadbackState
- readback_state
- NeedsCommit
- SetNeedsRedraw
- SetNeedsForcedRedrawForTimeout
- NeedsForcedRedrawForTimeout
- SetNeedsForcedRedrawForReadback
- NeedsForcedRedrawForReadback
- SetActiveTreeNeedsFirstDraw
- CanDraw
- Visible
- PendingActivationsShouldBeForced
- SetHasPendingTree
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TestFailedDrawsEventuallyForceDrawAfterNextCommit
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TestSetNeedsCommitIsNotLost
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TestForceCommitWhenReplacementActivationInProgress
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
#include "cc/scheduler/scheduler_state_machine.h"
#include "cc/scheduler/scheduler.h"
#include "testing/gtest/include/gtest/gtest.h"
#define EXPECT_ACTION_UPDATE_STATE(action) \
EXPECT_EQ(action, state.NextAction()) << *state.AsValue(); \
if (action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE || \
action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED) { \
EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE, \
state.begin_impl_frame_state()) \
<< *state.AsValue(); \
} \
state.UpdateState(action); \
if (action == SchedulerStateMachine::ACTION_NONE) { \
if (state.begin_impl_frame_state() == \
SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) \
state.OnBeginImplFrameDeadlinePending(); \
if (state.begin_impl_frame_state() == \
SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) \
state.OnBeginImplFrameIdle(); \
}
namespace cc {
namespace {
const SchedulerStateMachine::BeginImplFrameState all_begin_impl_frame_states[] =
{SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE, };
const SchedulerStateMachine::CommitState all_commit_states[] = {
SchedulerStateMachine::COMMIT_STATE_IDLE,
SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED,
SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION,
SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW};
class StateMachine : public SchedulerStateMachine {
public:
explicit StateMachine(const SchedulerSettings& scheduler_settings)
: SchedulerStateMachine(scheduler_settings) {}
void CreateAndInitializeOutputSurfaceWithActivatedCommit() {
DidCreateAndInitializeOutputSurface();
output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
}
void SetCommitState(CommitState cs) { commit_state_ = cs; }
CommitState CommitState() const { return commit_state_; }
ForcedRedrawOnTimeoutState ForcedRedrawState() const {
return forced_redraw_state_;
}
void SetBeginImplFrameState(BeginImplFrameState bifs) {
begin_impl_frame_state_ = bifs;
}
BeginImplFrameState begin_impl_frame_state() const {
return begin_impl_frame_state_;
}
OutputSurfaceState output_surface_state() const {
return output_surface_state_;
}
void SetReadbackState(SynchronousReadbackState rs) { readback_state_ = rs; }
SynchronousReadbackState readback_state() const { return readback_state_; }
bool NeedsCommit() const { return needs_commit_; }
void SetNeedsRedraw(bool b) { needs_redraw_ = b; }
void SetNeedsForcedRedrawForTimeout(bool b) {
forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT;
active_tree_needs_first_draw_ = true;
}
bool NeedsForcedRedrawForTimeout() const {
return forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE;
}
void SetNeedsForcedRedrawForReadback() {
readback_state_ = READBACK_STATE_WAITING_FOR_DRAW_AND_READBACK;
active_tree_needs_first_draw_ = true;
}
bool NeedsForcedRedrawForReadback() const {
return readback_state_ != READBACK_STATE_IDLE;
}
void SetActiveTreeNeedsFirstDraw(bool needs_first_draw) {
active_tree_needs_first_draw_ = needs_first_draw;
}
bool CanDraw() const { return can_draw_; }
bool Visible() const { return visible_; }
bool PendingActivationsShouldBeForced() const {
return SchedulerStateMachine::PendingActivationsShouldBeForced();
}
void SetHasPendingTree(bool has_pending_tree) {
has_pending_tree_ = has_pending_tree;
}
};
TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) {
SchedulerSettings default_scheduler_settings;
{
StateMachine state(default_scheduler_settings);
state.SetCanStart();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION)
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
state.SetNeedsRedraw(false);
state.SetVisible(true);
EXPECT_FALSE(state.BeginImplFrameNeeded());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_FALSE(state.BeginImplFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
}
{
StateMachine state(default_scheduler_settings);
state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
state.SetNeedsRedraw(false);
state.SetVisible(true);
state.SetNeedsCommit();
EXPECT_FALSE(state.BeginImplFrameNeeded());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_FALSE(state.BeginImplFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
}
{
StateMachine state(default_scheduler_settings);
state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetNeedsRedraw(false);
state.SetVisible(true);
state.SetNeedsCommit();
EXPECT_TRUE(state.BeginImplFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
}
{
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.UpdateState(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
state.CommitState());
EXPECT_FALSE(state.NeedsCommit());
}
}
TEST(SchedulerStateMachineTest, MainFrameBeforeDrawDisabled) {
SchedulerSettings scheduler_settings;
scheduler_settings.impl_side_painting = true;
scheduler_settings.main_frame_before_draw_enabled = false;
StateMachine state(scheduler_settings);
state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetNeedsRedraw(false);
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsCommit();
EXPECT_TRUE(state.BeginImplFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_EQ(state.CommitState(),
SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_EQ(state.CommitState(),
SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
state.SetNeedsCommit();
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_EQ(state.CommitState(),
SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
EXPECT_EQ(state.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_EQ(state.CommitState(),
SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_EQ(state.CommitState(),
SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
}
TEST(SchedulerStateMachineTest, MainFrameBeforeActivationEnabled) {
SchedulerSettings scheduler_settings;
scheduler_settings.impl_side_painting = true;
scheduler_settings.main_frame_before_activation_enabled = true;
StateMachine state(scheduler_settings);
state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetNeedsRedraw(false);
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsCommit();
EXPECT_TRUE(state.BeginImplFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_EQ(state.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.SetNeedsCommit();
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_EQ(state.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE);
}
TEST(SchedulerStateMachineTest,
TestFailedDrawForAnimationCheckerboardSetsNeedsCommitAndDoesNotDrawAgain) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsRedraw(true);
EXPECT_TRUE(state.RedrawPending());
EXPECT_TRUE(state.BeginImplFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_FALSE(state.RedrawPending());
EXPECT_FALSE(state.CommitPending());
state.DidDrawIfPossibleCompleted(
DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_TRUE(state.RedrawPending());
EXPECT_TRUE(state.CommitPending());
}
TEST(SchedulerStateMachineTest, TestFailedDrawForMissingHighResNeedsCommit) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsRedraw(true);
EXPECT_TRUE(state.RedrawPending());
EXPECT_TRUE(state.BeginImplFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_FALSE(state.RedrawPending());
EXPECT_FALSE(state.CommitPending());
state.DidDrawIfPossibleCompleted(
DrawSwapReadbackResult::DRAW_ABORTED_MISSING_HIGH_RES_CONTENT);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_FALSE(state.RedrawPending());
EXPECT_TRUE(state.CommitPending());
}
TEST(SchedulerStateMachineTest,
TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsRedraw(true);
EXPECT_TRUE(state.RedrawPending());
EXPECT_TRUE(state.BeginImplFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_FALSE(state.RedrawPending());
EXPECT_FALSE(state.CommitPending());
state.SetNeedsRedraw(true);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.DidDrawIfPossibleCompleted(
DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_TRUE(state.RedrawPending());
}
void TestFailedDrawsEventuallyForceDrawAfterNextCommit(
bool main_frame_before_draw_enabled) {
SchedulerSettings scheduler_settings;
scheduler_settings.main_frame_before_draw_enabled =
main_frame_before_draw_enabled;
scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ = 1;
StateMachine state(scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_TRUE(state.CommitPending());
state.SetNeedsRedraw(true);
state.OnBeginImplFrameDeadline();
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.RedrawPending());
EXPECT_TRUE(state.CommitPending());
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_TRUE(state.RedrawPending());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
if (main_frame_before_draw_enabled) {
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
}
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED);
}
TEST(SchedulerStateMachineTest,
TestFailedDrawsEventuallyForceDrawAfterNextCommit) {
bool main_frame_before_draw_enabled = false;
TestFailedDrawsEventuallyForceDrawAfterNextCommit(
main_frame_before_draw_enabled);
}
TEST(SchedulerStateMachineTest,
TestFailedDrawsEventuallyForceDrawAfterNextCommit_CommitBeforeDraw) {
bool main_frame_before_draw_enabled = true;
TestFailedDrawsEventuallyForceDrawAfterNextCommit(
main_frame_before_draw_enabled);
}
TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) {
SchedulerSettings scheduler_settings;
int draw_limit = 1;
scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ =
draw_limit;
scheduler_settings.impl_side_painting = true;
StateMachine state(scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_TRUE(state.CommitPending());
state.SetNeedsRedraw(true);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
for (int i = 0; i < draw_limit + 1; ++i) {
state.DidDrawIfPossibleCompleted(
DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
}
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_TRUE(state.BeginImplFrameNeeded());
EXPECT_TRUE(state.RedrawPending());
EXPECT_TRUE(state.CommitPending());
EXPECT_TRUE(state.ForcedRedrawState() ==
SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT);
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_TRUE(state.RedrawPending());
EXPECT_FALSE(state.CommitPending());
EXPECT_TRUE(state.ForcedRedrawState() ==
SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION);
for (int i = 0; i < draw_limit + 1; ++i) {
state.DidDrawIfPossibleCompleted(
DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
}
EXPECT_TRUE(state.RedrawPending());
EXPECT_TRUE(state.ForcedRedrawState() ==
SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION);
}
TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedInNextBeginImplFrame) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsRedraw(true);
EXPECT_TRUE(state.BeginImplFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_TRUE(state.RedrawPending());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
state.DidDrawIfPossibleCompleted(
DrawSwapReadbackResult::DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_TRUE(state.RedrawPending());
EXPECT_TRUE(state.BeginImplFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
}
TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsRedraw(true);
EXPECT_TRUE(state.BeginImplFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.SetNeedsRedraw(true);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_TRUE(state.BeginImplFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_TRUE(state.BeginImplFrameNeeded());
}
TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) {
SchedulerSettings default_scheduler_settings;
size_t num_commit_states =
sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState);
size_t num_begin_impl_frame_states =
sizeof(all_begin_impl_frame_states) /
sizeof(SchedulerStateMachine::BeginImplFrameState);
for (size_t i = 0; i < num_commit_states; ++i) {
for (size_t j = 0; j < num_begin_impl_frame_states; ++j) {
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetCommitState(all_commit_states[i]);
state.SetBeginImplFrameState(all_begin_impl_frame_states[j]);
bool visible =
(all_begin_impl_frame_states[j] !=
SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
state.SetVisible(visible);
EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
state.NextAction());
state.SetNeedsCommit();
EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
state.NextAction())
<< *state.AsValue();
}
}
for (size_t i = 0; i < num_commit_states; ++i) {
for (size_t j = 0; j < 2; ++j) {
bool request_readback = j;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetCanDraw(true);
state.SetCommitState(all_commit_states[i]);
state.SetBeginImplFrameState(
SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
if (request_readback) {
state.SetNeedsForcedRedrawForReadback();
} else {
state.SetNeedsRedraw(true);
state.SetVisible(true);
}
SchedulerStateMachine::Action expected_action;
if (request_readback) {
expected_action = SchedulerStateMachine::ACTION_DRAW_AND_READBACK;
} else if (all_commit_states[i] ==
SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT) {
expected_action = SchedulerStateMachine::ACTION_COMMIT;
} else {
expected_action =
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
}
EXPECT_NE(state.BeginImplFrameNeeded(), request_readback)
<< *state.AsValue();
EXPECT_EQ(state.NextAction(), expected_action) << *state.AsValue();
state.SetNeedsCommit();
EXPECT_NE(state.BeginImplFrameNeeded(), request_readback)
<< *state.AsValue();
EXPECT_EQ(state.NextAction(), expected_action) << *state.AsValue();
}
}
}
TEST(SchedulerStateMachineTest, TestNoCommitStatesRedrawWhenInvisible) {
SchedulerSettings default_scheduler_settings;
size_t num_commit_states =
sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState);
for (size_t i = 0; i < num_commit_states; ++i) {
for (size_t j = 0; j < 2; ++j) {
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetCommitState(all_commit_states[i]);
state.SetVisible(false);
state.SetNeedsRedraw(true);
if (j == 1) {
state.SetBeginImplFrameState(
SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
}
EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
state.NextAction());
state.SetNeedsCommit();
EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
state.NextAction())
<< *state.AsValue();
}
}
}
TEST(SchedulerStateMachineTest, TestCanRedraw_StopsDraw) {
SchedulerSettings default_scheduler_settings;
size_t num_commit_states =
sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState);
for (size_t i = 0; i < num_commit_states; ++i) {
for (size_t j = 0; j < 2; ++j) {
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetCommitState(all_commit_states[i]);
state.SetVisible(false);
state.SetNeedsRedraw(true);
if (j == 1)
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
state.SetCanDraw(false);
EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
state.NextAction());
}
}
}
TEST(SchedulerStateMachineTest,
TestCanRedrawWithWaitingForFirstDrawMakesProgress) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetActiveTreeNeedsFirstDraw(true);
state.SetNeedsCommit();
state.SetNeedsRedraw(true);
state.SetVisible(true);
state.SetCanDraw(false);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
}
void TestSetNeedsCommitIsNotLost(bool main_frame_before_draw_enabled) {
SchedulerSettings scheduler_settings;
scheduler_settings.main_frame_before_draw_enabled =
main_frame_before_draw_enabled;
StateMachine state(scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetNeedsCommit();
state.SetVisible(true);
state.SetCanDraw(true);
EXPECT_TRUE(state.BeginImplFrameNeeded());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
state.CommitState());
state.SetNeedsCommit();
EXPECT_TRUE(state.NeedsCommit());
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
state.CommitState());
EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
state.begin_impl_frame_state());
EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
state.OnBeginImplFrameDeadlinePending();
EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
state.begin_impl_frame_state());
EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
state.OnBeginImplFrameDeadline();
EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE,
state.begin_impl_frame_state());
EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
state.OnBeginImplFrameIdle();
EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
state.begin_impl_frame_state());
EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
state.begin_impl_frame_state());
EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
if (main_frame_before_draw_enabled) {
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
}
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_TRUE(state.active_tree_needs_first_draw());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
if (!main_frame_before_draw_enabled) {
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
}
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
}
TEST(SchedulerStateMachineTest, TestSetNeedsCommitIsNotLost) {
bool main_frame_before_draw_enabled = false;
TestSetNeedsCommitIsNotLost(main_frame_before_draw_enabled);
}
TEST(SchedulerStateMachineTest, TestSetNeedsCommitIsNotLost_CommitBeforeDraw) {
bool main_frame_before_draw_enabled = true;
TestSetNeedsCommitIsNotLost(main_frame_before_draw_enabled);
}
TEST(SchedulerStateMachineTest, TestFullCycle) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsCommit();
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
state.CommitState());
EXPECT_FALSE(state.NeedsCommit());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
state.CommitState());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_TRUE(state.active_tree_needs_first_draw());
EXPECT_TRUE(state.needs_redraw());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
EXPECT_FALSE(state.needs_redraw());
}
TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsCommit();
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
state.CommitState());
EXPECT_FALSE(state.NeedsCommit());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.SetNeedsCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
state.CommitState());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_TRUE(state.active_tree_needs_first_draw());
EXPECT_TRUE(state.needs_redraw());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
EXPECT_FALSE(state.needs_redraw());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
}
TEST(SchedulerStateMachineTest, TestRequestCommitInvisible) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetNeedsCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
}
TEST(SchedulerStateMachineTest, TestGoesInvisibleBeforeFinishCommit) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsCommit();
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
state.CommitState());
EXPECT_FALSE(state.NeedsCommit());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.SetVisible(false);
state.BeginMainFrameAborted(false);
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.SetVisible(true);
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
EXPECT_TRUE(state.NeedsCommit());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
state.CommitState());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
}
TEST(SchedulerStateMachineTest, AbortBeginMainFrameAndCancelCommit) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.DidCreateAndInitializeOutputSurface();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsCommit();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
state.CommitState());
EXPECT_FALSE(state.NeedsCommit());
EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
state.BeginMainFrameAborted(true);
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
EXPECT_FALSE(state.NeedsCommit());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
EXPECT_FALSE(state.NeedsCommit());
state.SetNeedsCommit();
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
state.NextAction());
}
TEST(SchedulerStateMachineTest, TestFirstContextCreation) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.SetVisible(true);
state.SetCanDraw(true);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.SetNeedsCommit();
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
}
TEST(SchedulerStateMachineTest, TestContextLostWhenCompletelyIdle) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
state.NextAction());
state.DidLoseOutputSurface();
EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
state.NextAction());
state.UpdateState(state.NextAction());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
}
TEST(SchedulerStateMachineTest,
TestContextLostWhenIdleAndCommitRequestedWhileRecreating) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
state.NextAction());
state.DidLoseOutputSurface();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.SetNeedsCommit();
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.DidCreateAndInitializeOutputSurface();
EXPECT_FALSE(state.RedrawPending());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
state.CommitState());
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_TRUE(state.RedrawPending());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
state.NextAction());
state.SetCanDraw(false);
EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT,
state.NextAction());
state.SetCanDraw(true);
EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
state.NextAction());
}
TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) {
SchedulerSettings scheduler_settings;
StateMachine state(scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsCommit();
state.SetNeedsRedraw(true);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.DidLoseOutputSurface();
state.SetNeedsRedraw(true);
EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_TRUE(state.active_tree_needs_first_draw());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
state.begin_impl_frame_state());
EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
state.NextAction());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
state.begin_impl_frame_state());
EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
state.OnBeginImplFrameDeadlinePending();
EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
state.begin_impl_frame_state());
EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
state.OnBeginImplFrameDeadline();
EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE,
state.begin_impl_frame_state());
EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
}
TEST(SchedulerStateMachineTest,
TestContextLostWhileCommitInProgressAndAnotherCommitRequested) {
SchedulerSettings scheduler_settings;
StateMachine state(scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.SetNeedsRedraw(true);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.DidLoseOutputSurface();
state.SetNeedsRedraw(true);
state.SetNeedsCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_TRUE(state.active_tree_needs_first_draw());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
state.begin_impl_frame_state());
EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
state.NextAction());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
state.begin_impl_frame_state());
EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
state.OnBeginImplFrameDeadlinePending();
EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
state.begin_impl_frame_state());
EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
state.OnBeginImplFrameDeadline();
EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE,
state.begin_impl_frame_state());
EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
state.OnBeginImplFrameIdle();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
}
TEST(SchedulerStateMachineTest, TestFinishAllRenderingWhileContextLost) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.DidLoseOutputSurface();
state.SetNeedsForcedRedrawForReadback();
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
state.CommitState());
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
state.OnBeginImplFrameDeadline();
EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
state.OnBeginImplFrameIdle();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
state.SetNeedsForcedRedrawForReadback();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
}
TEST(SchedulerStateMachineTest, DontDrawBeforeCommitAfterLostOutputSurface) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsRedraw(true);
state.DidLoseOutputSurface();
EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
state.NextAction());
state.UpdateState(state.NextAction());
state.DidCreateAndInitializeOutputSurface();
EXPECT_FALSE(state.RedrawPending());
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
state.NextAction());
}
TEST(SchedulerStateMachineTest,
TestPendingActivationsShouldBeForcedAfterLostOutputSurface) {
SchedulerSettings settings;
settings.impl_side_painting = true;
StateMachine state(settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetCommitState(
SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
state.DidLoseOutputSurface();
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_TRUE(state.PendingActivationsShouldBeForced());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE);
EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
}
TEST(SchedulerStateMachineTest,
TestSendBeginMainFrameWhenInvisibleAndForceCommit) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(false);
state.SetNeedsForcedCommitForReadback();
EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
state.NextAction());
}
TEST(SchedulerStateMachineTest,
TestSendBeginMainFrameWhenCanStartFalseAndForceCommit) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsForcedCommitForReadback();
EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
state.NextAction());
}
TEST(SchedulerStateMachineTest, DontMakeNewCommitAfterDrawingReplaceCommit) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetCommitState(
SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
state.SetNeedsForcedCommitForReadback();
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_READBACK,
state.NextAction());
state.UpdateState(state.NextAction());
EXPECT_EQ(
SchedulerStateMachine::READBACK_STATE_WAITING_FOR_REPLACEMENT_COMMIT,
state.readback_state());
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
state.CommitState());
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
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);
}
TEST(SchedulerStateMachineTest, TestFinishCommitWhenCommitInProgress) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(false);
state.SetCommitState(
SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
state.SetNeedsCommit();
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
state.UpdateState(state.NextAction());
EXPECT_TRUE(state.active_tree_needs_first_draw());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
}
TEST(SchedulerStateMachineTest, TestFinishCommitWhenForcedCommitInProgress) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(false);
state.SetCommitState(
SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
state.SetNeedsForcedCommitForReadback();
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_TRUE(state.active_tree_needs_first_draw());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK);
EXPECT_NE(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
state.NextAction());
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
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);
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);
state.SetNeedsForcedCommitForReadback();
EXPECT_FALSE(state.NeedsCommit());
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE);
EXPECT_EQ(SchedulerStateMachine::READBACK_STATE_NEEDS_BEGIN_MAIN_FRAME,
state.readback_state());
EXPECT_TRUE(state.NeedsCommit());
if (settings.main_frame_before_draw_enabled) {
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
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_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
if (!settings.main_frame_before_draw_enabled) {
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_EQ(SchedulerStateMachine::READBACK_STATE_WAITING_FOR_COMMIT,
state.readback_state());
}
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_NONE);
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);
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_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);
}
TEST(SchedulerStateMachineTest,
ForceCommitWhenReplacementActivationInProgressAndMainFrameEnabled) {
bool main_frame_before_draw_enabled = true;
TestForceCommitWhenReplacementActivationInProgress(
main_frame_before_draw_enabled);
}
TEST(SchedulerStateMachineTest,
ForceCommitWhenReplacementActivationInProgressAndMainFrameDisabled) {
bool main_frame_before_draw_enabled = false;
TestForceCommitWhenReplacementActivationInProgress(
main_frame_before_draw_enabled);
}
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);
state.SetCommitState(
SchedulerStateMachine::COMMIT_STATE_IDLE);
state.SetReadbackState(
SchedulerStateMachine::READBACK_STATE_WAITING_FOR_REPLACEMENT_ACTIVATION);
state.SetHasPendingTree(true);
state.SetNeedsCommit();
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
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);
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_NONE);
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_NONE);
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
}
TEST(SchedulerStateMachineTest, TestInitialActionsWhenContextLost) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsCommit();
state.DidLoseOutputSurface();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
state.DidCreateAndInitializeOutputSurface();
EXPECT_EQ(state.output_surface_state(),
SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT);
state.SetVisible(false);
EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction())
<< *state.AsValue();
state.SetNeedsForcedCommitForReadback();
EXPECT_EQ(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME, state.NextAction())
<< *state.AsValue();
}
TEST(SchedulerStateMachineTest, TestImmediateFinishCommit) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsForcedCommitForReadback();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
state.CommitState());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_TRUE(state.active_tree_needs_first_draw());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK);
state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
state.CommitState());
}
TEST(SchedulerStateMachineTest, TestImmediateFinishCommitDuringCommit) {
SchedulerSettings scheduler_settings;
StateMachine state(scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.SetNeedsForcedCommitForReadback();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
state.CommitState());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_TRUE(state.active_tree_needs_first_draw());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK);
state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
state.CommitState())
<< *state.AsValue();
}
TEST(SchedulerStateMachineTest, ImmediateBeginMainFrameAbortedWhileInvisible) {
SchedulerSettings scheduler_settings;
StateMachine state(scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.SetNeedsCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.SetNeedsForcedCommitForReadback();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
state.CommitState());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_TRUE(state.active_tree_needs_first_draw());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK);
state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
state.CommitState())
<< *state.AsValue();
state.SetVisible(false);
state.BeginMainFrameAborted(false);
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
EXPECT_TRUE(state.NeedsCommit());
}
TEST(SchedulerStateMachineTest, ImmediateFinishCommitWhileCantDraw) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(false);
state.SetNeedsCommit();
state.UpdateState(state.NextAction());
state.SetNeedsForcedCommitForReadback();
state.UpdateState(state.NextAction());
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
state.CommitState());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_TRUE(state.active_tree_needs_first_draw());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_READBACK);
state.DidDrawIfPossibleCompleted(DrawSwapReadbackResult::DRAW_SUCCESS);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
}
TEST(SchedulerStateMachineTest, ReportIfNotDrawing) {
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.SetCanDraw(false);
state.SetVisible(true);
EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
state.SetCanDraw(true);
state.SetVisible(false);
EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
state.SetCanDraw(false);
state.SetVisible(false);
EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
state.SetCanDraw(true);
state.SetVisible(true);
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;
StateMachine state(settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
state.SetNeedsRedraw(true);
state.SetNeedsCommit();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
state.BeginMainFrameAborted(true);
EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
}
TEST(SchedulerStateMachineTest, TestTriggerDeadlineEarlyForSmoothness) {
SchedulerSettings settings;
settings.impl_side_painting = true;
StateMachine state(settings);
state.SetCanStart();
state.UpdateState(state.NextAction());
state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
state.SetVisible(true);
state.SetCanDraw(true);
state.OnBeginImplFrame(BeginFrameArgs::CreateForTesting());
state.SetNeedsRedraw(true);
state.SetNeedsCommit();
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
state.SetSmoothnessTakesPriority(true);
EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
}
}
}