Chromium Code Reviews| Index: cc/scheduler/scheduler_state_machine_unittest.cc |
| diff --git a/cc/scheduler/scheduler_state_machine_unittest.cc b/cc/scheduler/scheduler_state_machine_unittest.cc |
| index aa5c4aac39a1164318196bfee92197fcbc1a2909..aedd7955597a2ccf75a1cbf40f6def4e4631a70c 100644 |
| --- a/cc/scheduler/scheduler_state_machine_unittest.cc |
| +++ b/cc/scheduler/scheduler_state_machine_unittest.cc |
| @@ -150,6 +150,10 @@ class StateMachine : public SchedulerStateMachine { |
| has_pending_tree_ = has_pending_tree; |
| } |
| + bool needs_impl_side_invalidation() const { |
| + return needs_impl_side_invalidation_; |
| + } |
| + |
| using SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately; |
| using SchedulerStateMachine::ProactiveBeginFrameWanted; |
| using SchedulerStateMachine::WillCommit; |
| @@ -200,6 +204,10 @@ void PerformAction(StateMachine* sm, SchedulerStateMachine::Action action) { |
| case SchedulerStateMachine::ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK: |
| sm->WillInvalidateCompositorFrameSink(); |
| return; |
| + |
| + case SchedulerStateMachine::ACTION_PERFORM_IMPL_SIDE_INVALIDATION: |
| + sm->WillPerformImplSideInvalidation(); |
| + return; |
| } |
| } |
| @@ -2123,5 +2131,256 @@ TEST(SchedulerStateMachineTest, |
| SchedulerStateMachine::ACTION_BEGIN_COMPOSITOR_FRAME_SINK_CREATION); |
| } |
| +TEST(SchedulerStateMachineTest, NoImplSideInvalidationsWhileInvisible) { |
| + SchedulerSettings settings; |
| + StateMachine state(settings); |
| + SET_UP_STATE(state); |
| + |
| + // No impl-side invalidations should be performed while we are not visible. |
| + state.SetVisible(false); |
| + state.SetNeedsImplSideInvalidation(); |
| + state.OnBeginImplFrame(); |
| + state.OnBeginImplFrameDeadline(); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
| +} |
| + |
| +TEST(SchedulerStateMachineTest, |
| + NoImplSideInvalidationsWhenBeginFrameSourcePaused) { |
| + SchedulerSettings settings; |
| + StateMachine state(settings); |
| + SET_UP_STATE(state); |
| + |
| + // No impl-side invalidations should be performed while we can not make impl |
| + // frames. |
| + state.SetBeginFrameSourcePaused(true); |
| + state.SetNeedsImplSideInvalidation(); |
| + state.OnBeginImplFrame(); |
| + state.OnBeginImplFrameDeadline(); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
| +} |
| + |
| +TEST(SchedulerStateMachineTest, ImplSideInvalidationOnlyInsideDeadline) { |
| + SchedulerSettings settings; |
| + StateMachine state(settings); |
| + SET_UP_STATE(state); |
| + |
| + state.SetNeedsImplSideInvalidation(); |
| + state.OnBeginImplFrame(); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
| + state.OnBeginImplFrameDeadline(); |
| + EXPECT_ACTION_UPDATE_STATE( |
| + SchedulerStateMachine::ACTION_PERFORM_IMPL_SIDE_INVALIDATION); |
| +} |
| + |
| +TEST(SchedulerStateMachineTest, |
| + NoImplSideInvalidationWithoutCompositorFrameSink) { |
| + SchedulerSettings settings; |
| + StateMachine state(settings); |
| + SET_UP_STATE(state); |
| + |
| + // Impl-side invalidations should not be triggered till the frame sink is |
| + // initialized. |
| + state.DidLoseCompositorFrameSink(); |
| + EXPECT_ACTION_UPDATE_STATE( |
| + SchedulerStateMachine::ACTION_BEGIN_COMPOSITOR_FRAME_SINK_CREATION); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
| + |
| + // No impl-side invalidations should be performed during frame sink creation. |
| + state.SetNeedsImplSideInvalidation(); |
| + state.OnBeginImplFrame(); |
| + state.OnBeginImplFrameDeadline(); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
| + |
| + // Initializing the CompositorFrameSink puts us in a state waiting for the |
| + // first commit. |
| + state.DidCreateAndInitializeCompositorFrameSink(); |
| + state.OnBeginImplFrame(); |
| + EXPECT_ACTION_UPDATE_STATE( |
| + SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); |
| + state.NotifyBeginMainFrameStarted(); |
| + state.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES); |
| + state.OnBeginImplFrameDeadline(); |
| + EXPECT_ACTION_UPDATE_STATE( |
| + SchedulerStateMachine::ACTION_PERFORM_IMPL_SIDE_INVALIDATION); |
| +} |
| + |
| +TEST(SchedulerStateMachineTest, ImplSideInvalidationWhenPendingTreeExists) { |
| + SchedulerSettings settings; |
| + StateMachine state(settings); |
| + SET_UP_STATE(state); |
| + |
| + // Set up request for the main frame, commit and create the pending tree. |
| + state.SetNeedsBeginMainFrame(); |
| + state.OnBeginImplFrame(); |
| + EXPECT_ACTION_UPDATE_STATE( |
| + SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); |
| + state.NotifyBeginMainFrameStarted(); |
| + state.NotifyReadyToCommit(); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); |
| + |
| + // Request an impl-side invalidation after the commit. The request should wait |
| + // till the current pending tree is activated. |
|
sunnyps
2017/02/23 00:33:21
Can you trigger the deadline here and activate in
Khushal
2017/02/23 01:25:43
Hmmm, in fact I wanted to activate within this fra
|
| + state.SetNeedsImplSideInvalidation(); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
| + |
| + // Activate the pending tree. Since the commit fills the impl-side |
| + // invalidation funnel as well, the request should wait until the next |
| + // BeginFrame. |
| + state.NotifyReadyToActivate(); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE); |
| + state.OnBeginImplFrameDeadline(); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
| + |
| + // Since there is no main frame request, this should perform impl-side |
| + // invalidations. |
| + state.OnBeginImplFrame(); |
| + state.OnBeginImplFrameDeadline(); |
| + EXPECT_ACTION_UPDATE_STATE( |
| + SchedulerStateMachine::ACTION_PERFORM_IMPL_SIDE_INVALIDATION); |
| +} |
| + |
| +TEST(SchedulerStateMachineTest, ImplSideInvalidationWhileMainFramePending) { |
|
sunnyps
2017/02/23 00:33:21
nit: WhileReadyToCommit?
Khushal
2017/02/23 01:25:43
Done.
|
| + SchedulerSettings settings; |
| + StateMachine state(settings); |
| + SET_UP_STATE(state); |
| + |
| + // Set up request for the main frame. |
| + state.SetNeedsBeginMainFrame(); |
| + state.OnBeginImplFrame(); |
| + EXPECT_ACTION_UPDATE_STATE( |
| + SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
| + |
| + // Request an impl-side invalidation. The request should wait till a response |
| + // is received from the main thread. |
| + state.SetNeedsImplSideInvalidation(); |
| + EXPECT_TRUE(state.needs_impl_side_invalidation()); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
|
sunnyps
2017/02/23 00:33:21
We should check for invalidation in the deadline.
Khushal
2017/02/23 01:25:43
Done.
|
| + |
| + // Perform a commit, the impl-side invalidation request should be reset since |
| + // they will be merged with the commit. |
| + state.NotifyBeginMainFrameStarted(); |
| + state.NotifyReadyToCommit(); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); |
| + EXPECT_FALSE(state.needs_impl_side_invalidation()); |
| +} |
| + |
| +TEST(SchedulerStateMachineTest, |
| + ConsecutiveImplSideInvalidationsWaitForBeginFrame) { |
| + SchedulerSettings settings; |
| + StateMachine state(settings); |
| + SET_UP_STATE(state); |
| + |
| + // Set up a request for impl-side invalidation. |
| + state.SetNeedsImplSideInvalidation(); |
| + state.OnBeginImplFrame(); |
| + state.OnBeginImplFrameDeadline(); |
| + EXPECT_ACTION_UPDATE_STATE( |
| + SchedulerStateMachine::ACTION_PERFORM_IMPL_SIDE_INVALIDATION); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
| + |
| + // Request another invalidation, which should wait until the pending tree is |
| + // activated *and* we start the next BeginFrame. |
| + state.SetNeedsImplSideInvalidation(); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
| + state.NotifyReadyToActivate(); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
| + |
| + // Now start the next frame, which will first draw the active tree and then |
| + // perform the pending impl-side invalidation request. |
| + state.OnBeginImplFrame(); |
| + state.OnBeginImplFrameDeadline(); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); |
| + EXPECT_ACTION_UPDATE_STATE( |
| + SchedulerStateMachine::ACTION_PERFORM_IMPL_SIDE_INVALIDATION); |
| +} |
| + |
| +TEST(SchedulerStateMachineTest, ImplSideInvalidationsThrottledOnDraw) { |
| + // In commit_to_active_tree mode, performing the next invalidation should be |
| + // throttled on the active tree being drawn. |
| + SchedulerSettings settings; |
| + settings.commit_to_active_tree = true; |
| + StateMachine state(settings); |
| + SET_UP_STATE(state); |
| + |
| + // Commit to the sync tree, activate and draw. |
| + state.SetNeedsBeginMainFrame(); |
| + state.OnBeginImplFrame(); |
| + EXPECT_ACTION_UPDATE_STATE( |
| + SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); |
| + state.NotifyBeginMainFrameStarted(); |
| + state.NotifyReadyToCommit(); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); |
| + state.NotifyReadyToActivate(); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE); |
| + state.NotifyReadyToDraw(); |
| + state.OnBeginImplFrameDeadline(); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); |
| + state.DidSubmitCompositorFrame(); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
| + |
| + // Request impl-side invalidation and start a new frame, which should be |
| + // blocked on the ack for the previous frame. |
| + state.SetNeedsImplSideInvalidation(); |
| + state.OnBeginImplFrame(); |
| + state.OnBeginImplFrameDeadline(); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
| + |
| + // Ack the previous frame and begin impl frame, which shoul perrform the |
|
sunnyps
2017/02/23 00:33:21
nit: should perform
Khushal
2017/02/23 01:25:43
Done.
|
| + // invalidation now. |
| + state.DidReceiveCompositorFrameAck(); |
| + state.OnBeginImplFrame(); |
| + state.OnBeginImplFrameDeadline(); |
| + EXPECT_ACTION_UPDATE_STATE( |
| + SchedulerStateMachine::ACTION_PERFORM_IMPL_SIDE_INVALIDATION); |
| +} |
| + |
| +TEST(SchedulerStateMachineTest, ImplSideInvalidationsAfterAbortedCommits) { |
| + SchedulerSettings settings; |
| + StateMachine state(settings); |
| + SET_UP_STATE(state); |
| + |
| + // Set up request for the main frame. |
| + state.SetNeedsBeginMainFrame(); |
| + state.OnBeginImplFrame(); |
| + EXPECT_ACTION_UPDATE_STATE( |
| + SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
| + |
| + // Request an impl-side invalidation, which should wait until a response is |
| + // received for the BeginMainFrame. |
| + state.SetNeedsImplSideInvalidation(); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
|
sunnyps
2017/02/23 00:33:21
Check for invalidation in deadline.
Khushal
2017/02/23 01:25:43
Actually, I don't know if the test makes sense any
|
| + |
| + // Request another main frame, and abort the sent BeginMainFrame. Aborting |
| + // this frame should create a pending tree for impl-side invalidation. |
| + state.SetNeedsBeginMainFrame(); |
| + state.NotifyBeginMainFrameStarted(); |
| + state.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES); |
| + state.OnBeginImplFrameDeadline(); |
| + EXPECT_ACTION_UPDATE_STATE( |
| + SchedulerStateMachine::ACTION_PERFORM_IMPL_SIDE_INVALIDATION); |
| +} |
| + |
| +TEST(SchedulerStateMachineTest, PrepareTilesWaitForImplSideInvalidation) { |
| + // PrepareTiles |
| + SchedulerSettings settings; |
| + StateMachine state(settings); |
| + SET_UP_STATE(state); |
| + |
| + // Request a PrepareTiles and impl-side invalidation. The impl-side |
| + // invalidation should run first, since it will perform PrepareTiles as well. |
| + state.SetNeedsImplSideInvalidation(); |
| + state.SetNeedsPrepareTiles(); |
| + state.OnBeginImplFrame(); |
| + state.OnBeginImplFrameDeadline(); |
| + EXPECT_ACTION_UPDATE_STATE( |
| + SchedulerStateMachine::ACTION_PERFORM_IMPL_SIDE_INVALIDATION); |
| + state.DidPrepareTiles(); |
| + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
| +} |
| + |
| } // namespace |
| } // namespace cc |