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..033e2fb5b3701e639ef0985a6a78825822a7e457 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->WillRunImplSideInvalidation(); |
+ return; |
} |
} |
@@ -2123,5 +2131,254 @@ TEST(SchedulerStateMachineTest, |
SchedulerStateMachine::ACTION_BEGIN_COMPOSITOR_FRAME_SINK_CREATION); |
} |
+TEST(SchedulerStateMachineTest, NoImplSideInvalidationsWhileInvsible) { |
+ SchedulerSettings settings; |
+ StateMachine state(settings); |
+ SET_UP_STATE(state); |
+ |
+ // No impl-side invalidations should be performed while we are not visible. |
sunnyps
2017/02/14 21:40:18
You should start a BeginFrame before testing inval
Khushal
2017/02/15 00:56:33
I'm not sure I followed this. The |impl_side_inval
sunnyps
2017/02/20 23:19:22
Ah, I assumed that the funnel is initialized to tr
|
+ state.SetVisible(false); |
+ state.SetNeedsImplSideInvalidation(); |
+ 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); |
sunnyps
2017/02/14 21:40:19
Same here.
|
+ state.SetNeedsImplSideInvalidation(); |
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
+} |
+ |
+TEST(SchedulerStateMachineTest, |
+ NoImplSideInvalidationWithoutCompositorFrameSink) { |
+ SchedulerSettings settings; |
+ StateMachine state(settings); |
+ SET_UP_STATE(state); |
+ |
+ // Impl-side invalidations should not be triggered till the frame sink is |
sunnyps
2017/02/14 21:40:19
Same here.
|
+ // 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.OnBeginImplFrame(); |
+ state.SetNeedsImplSideInvalidation(); |
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
+ |
+ // Initializing the CompositorFrameSink puts us in a state waiting for the |
+ // first commit. |
+ state.DidCreateAndInitializeCompositorFrameSink(); |
+ EXPECT_ACTION_UPDATE_STATE( |
+ SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); |
+ state.NotifyBeginMainFrameStarted(); |
+ state.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES); |
+ 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); |
+ 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); |
+ |
+ // Request an impl-side invalidation after the commit. The request should wait |
+ // till the current pending tree is activated. |
+ 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); |
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
+ |
+ // Since there is no main frame request, this should perform impl-side |
+ // invalidations. |
+ state.OnBeginImplFrame(); |
+ EXPECT_ACTION_UPDATE_STATE( |
+ SchedulerStateMachine::ACTION_PERFORM_IMPL_SIDE_INVALIDATION); |
+} |
+ |
+TEST(SchedulerStateMachineTest, ImplSideInvalidationWhileMainFramePending) { |
+ 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); |
+ |
+ // 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(); |
+ EXPECT_ACTION_UPDATE_STATE( |
+ SchedulerStateMachine::ACTION_PERFORM_IMPL_SIDE_INVALIDATION); |
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
+ |
+ // Request another invalidation before the pending tree is activated. The |
+ // request should wait until 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); |
+ state.OnBeginImplFrame(); |
+ 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 and activate. |
+ 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); |
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
+ |
+ // BeginImplFrame deadline, the draw is blocked on NotifyReadyToDraw. |
+ state.OnBeginImplFrameDeadline(); |
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
+ |
+ // Request impl-side invalidation which should be blocked on the active tree |
+ // being drawn and submitted. |
+ state.SetNeedsImplSideInvalidation(); |
+ state.OnBeginImplFrame(); |
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
+ state.NotifyReadyToDraw(); |
+ state.OnBeginImplFrameDeadline(); |
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); |
+ state.DidSubmitCompositorFrame(); |
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
+ state.DidReceiveCompositorFrameAck(); |
+ |
+ // The frame being acked should perform impl-side invalidation. |
+ EXPECT_ACTION_UPDATE_STATE( |
+ SchedulerStateMachine::ACTION_PERFORM_IMPL_SIDE_INVALIDATION); |
+} |
+ |
+TEST(SchedulerStateMachineTest, |
+ ImplSideInvalidationsTakePriorityForAbortedCommits) { |
+ 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); |
+ |
+ // Request another main frame, and abort the sent BeginMainFrame. Aborting |
+ // this frame should create a pending tree for impl-side invalidation. |
+ state.SetNeedsBeginMainFrame(); |
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
+ state.NotifyBeginMainFrameStarted(); |
+ state.BeginMainFrameAborted(CommitEarlyOutReason::FINISHED_NO_UPDATES); |
sunnyps
2017/02/14 21:40:18
After aborting the commit send BeginMainFrame agai
Khushal
2017/02/15 00:56:33
Done.
Khushal
2017/02/15 03:23:52
Actually, while adding the SchedulerTest for this,
|
+ EXPECT_ACTION_UPDATE_STATE( |
+ SchedulerStateMachine::ACTION_PERFORM_IMPL_SIDE_INVALIDATION); |
+} |
+ |
+TEST(SchedulerStateMachineTest, |
+ ImplSideInvalidationsBlockedOnSendingBeginMainFrame) { |
+ SchedulerSettings settings; |
+ StateMachine state(settings); |
+ SET_UP_STATE(state); |
+ |
+ // BeginMainFrame, commit and activate the sync 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); |
+ state.NotifyReadyToActivate(); |
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE); |
+ |
+ // Set the tree priority to smoothness mode and request a main frame and |
+ // impl-side invalidations. |
sunnyps
2017/02/14 21:40:19
Can you explain what tree priority has to do with
Khushal
2017/02/15 00:56:33
This was just to get a case for:
if (CouldSendBe
|
+ state.OnBeginImplFrameDeadline(); |
+ state.OnBeginImplFrame(); |
+ state.SetTreePrioritiesAndScrollState( |
+ TreePriority::SMOOTHNESS_TAKES_PRIORITY, |
+ ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER); |
+ state.SetNeedsBeginMainFrame(); |
+ state.SetNeedsImplSideInvalidation(); |
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); |
+ |
+ // The impl-side invalidations should wait until BeginMainFrame is sent and |
+ // a response is received. |
+ state.SetTreePrioritiesAndScrollState( |
+ TreePriority::SMOOTHNESS_TAKES_PRIORITY, |
+ ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER); |
+ EXPECT_ACTION_UPDATE_STATE( |
+ SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); |
+ state.NotifyBeginMainFrameStarted(); |
+ state.NotifyReadyToCommit(); |
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); |
+ EXPECT_FALSE(state.needs_impl_side_invalidation()); |
+} |
+ |
} // namespace |
} // namespace cc |