Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / cc / scheduler / scheduler_state_machine_unittest.cc
1 // Copyright 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cc/scheduler/scheduler_state_machine.h"
6
7 #include "base/debug/trace_event.h"
8 #include "cc/scheduler/scheduler.h"
9 #include "cc/test/begin_frame_args_test.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 #define EXPECT_ACTION_UPDATE_STATE(action)                                   \
13   EXPECT_STREQ(SchedulerStateMachine::ActionToString(action),                \
14                SchedulerStateMachine::ActionToString(state.NextAction()))    \
15       << state.AsValue()->ToString();                                        \
16   if (action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE ||   \
17       action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED) {        \
18     EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE, \
19               state.begin_impl_frame_state())                                \
20         << state.AsValue()->ToString();                                      \
21   }                                                                          \
22   state.UpdateState(action);                                                 \
23   if (action == SchedulerStateMachine::ACTION_NONE) {                        \
24     if (state.begin_impl_frame_state() ==                                    \
25         SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING)  \
26       state.OnBeginImplFrameDeadlinePending();                               \
27     if (state.begin_impl_frame_state() ==                                    \
28         SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)       \
29       state.OnBeginImplFrameIdle();                                          \
30   }
31
32 namespace cc {
33
34 namespace {
35
36 const SchedulerStateMachine::BeginImplFrameState all_begin_impl_frame_states[] =
37     {SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
38      SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
39      SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
40      SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE, };
41
42 const SchedulerStateMachine::CommitState all_commit_states[] = {
43     SchedulerStateMachine::COMMIT_STATE_IDLE,
44     SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
45     SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED,
46     SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
47     SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION};
48
49 // Exposes the protected state fields of the SchedulerStateMachine for testing
50 class StateMachine : public SchedulerStateMachine {
51  public:
52   explicit StateMachine(const SchedulerSettings& scheduler_settings)
53       : SchedulerStateMachine(scheduler_settings) {}
54
55   void CreateAndInitializeOutputSurfaceWithActivatedCommit() {
56     DidCreateAndInitializeOutputSurface();
57     output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
58   }
59
60   void SetCommitState(CommitState cs) { commit_state_ = cs; }
61   CommitState CommitState() const { return commit_state_; }
62
63   ForcedRedrawOnTimeoutState ForcedRedrawState() const {
64     return forced_redraw_state_;
65   }
66
67   void SetBeginImplFrameState(BeginImplFrameState bifs) {
68     begin_impl_frame_state_ = bifs;
69   }
70
71   BeginImplFrameState begin_impl_frame_state() const {
72     return begin_impl_frame_state_;
73   }
74
75   OutputSurfaceState output_surface_state() const {
76     return output_surface_state_;
77   }
78
79   bool NeedsCommit() const { return needs_commit_; }
80
81   void SetNeedsRedraw(bool b) { needs_redraw_ = b; }
82
83   void SetNeedsForcedRedrawForTimeout(bool b) {
84     forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT;
85     active_tree_needs_first_draw_ = true;
86   }
87   bool NeedsForcedRedrawForTimeout() const {
88     return forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE;
89   }
90
91   void SetActiveTreeNeedsFirstDraw(bool needs_first_draw) {
92     active_tree_needs_first_draw_ = needs_first_draw;
93   }
94
95   bool CanDraw() const { return can_draw_; }
96   bool Visible() const { return visible_; }
97
98   bool PendingActivationsShouldBeForced() const {
99     return SchedulerStateMachine::PendingActivationsShouldBeForced();
100   }
101
102   void SetHasPendingTree(bool has_pending_tree) {
103     has_pending_tree_ = has_pending_tree;
104   }
105 };
106
107 TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) {
108   SchedulerSettings default_scheduler_settings;
109
110   // If no commit needed, do nothing.
111   {
112     StateMachine state(default_scheduler_settings);
113     state.SetCanStart();
114     EXPECT_ACTION_UPDATE_STATE(
115         SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION)
116     state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
117     state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
118     state.SetNeedsRedraw(false);
119     state.SetVisible(true);
120
121     EXPECT_FALSE(state.BeginFrameNeeded());
122
123     EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
124     EXPECT_FALSE(state.BeginFrameNeeded());
125     state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
126
127     EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
128     state.OnBeginImplFrameDeadline();
129   }
130
131   // If commit requested but can_start is still false, do nothing.
132   {
133     StateMachine state(default_scheduler_settings);
134     state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
135     state.SetNeedsRedraw(false);
136     state.SetVisible(true);
137     state.SetNeedsCommit();
138
139     EXPECT_FALSE(state.BeginFrameNeeded());
140
141     EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
142     EXPECT_FALSE(state.BeginFrameNeeded());
143     state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
144     EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
145     state.OnBeginImplFrameDeadline();
146   }
147
148   // If commit requested, begin a main frame.
149   {
150     StateMachine state(default_scheduler_settings);
151     state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
152     state.SetCanStart();
153     state.UpdateState(state.NextAction());
154     state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
155     state.SetNeedsRedraw(false);
156     state.SetVisible(true);
157     state.SetNeedsCommit();
158
159     EXPECT_TRUE(state.BeginFrameNeeded());
160
161     state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
162     EXPECT_ACTION_UPDATE_STATE(
163         SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
164   }
165
166   // Begin the frame, make sure needs_commit and commit_state update correctly.
167   {
168     StateMachine state(default_scheduler_settings);
169     state.SetCanStart();
170     state.UpdateState(state.NextAction());
171     state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
172     state.SetVisible(true);
173     state.UpdateState(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
174     EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
175               state.CommitState());
176     EXPECT_FALSE(state.NeedsCommit());
177   }
178 }
179
180 // Explicitly test main_frame_before_activation_enabled = true
181 TEST(SchedulerStateMachineTest, MainFrameBeforeActivationEnabled) {
182   SchedulerSettings scheduler_settings;
183   scheduler_settings.impl_side_painting = true;
184   scheduler_settings.main_frame_before_activation_enabled = true;
185   StateMachine state(scheduler_settings);
186   state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
187   state.SetCanStart();
188   state.UpdateState(state.NextAction());
189   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
190   state.SetNeedsRedraw(false);
191   state.SetVisible(true);
192   state.SetCanDraw(true);
193   state.SetNeedsCommit();
194
195   EXPECT_TRUE(state.BeginFrameNeeded());
196
197   // Commit to the pending tree.
198   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
199   EXPECT_ACTION_UPDATE_STATE(
200       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
201   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
202
203   state.NotifyBeginMainFrameStarted();
204   state.NotifyReadyToCommit();
205   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
206   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
207   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
208
209   state.OnBeginImplFrameDeadline();
210   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
211
212   // Verify that the next commit starts while there is still a pending tree.
213   state.SetNeedsCommit();
214   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
215   EXPECT_ACTION_UPDATE_STATE(
216       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
217   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
218
219   // Verify the pending commit doesn't overwrite the pending
220   // tree until the pending tree has been activated.
221   state.NotifyBeginMainFrameStarted();
222   state.NotifyReadyToCommit();
223   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
224
225   // Verify NotifyReadyToActivate unblocks activation, draw, and
226   // commit in that order.
227   state.NotifyReadyToActivate();
228   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
229   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
230
231   EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
232   state.OnBeginImplFrameDeadline();
233   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
234   EXPECT_ACTION_UPDATE_STATE(
235       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
236   state.DidSwapBuffers();
237   state.DidSwapBuffersComplete();
238   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
239   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
240   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
241 }
242
243 TEST(SchedulerStateMachineTest,
244      TestFailedDrawForAnimationCheckerboardSetsNeedsCommitAndDoesNotDrawAgain) {
245   SchedulerSettings default_scheduler_settings;
246   StateMachine state(default_scheduler_settings);
247   state.SetCanStart();
248   state.UpdateState(state.NextAction());
249   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
250   state.SetVisible(true);
251   state.SetCanDraw(true);
252   state.SetNeedsRedraw(true);
253   EXPECT_TRUE(state.RedrawPending());
254   EXPECT_TRUE(state.BeginFrameNeeded());
255   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
256   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
257   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
258   state.OnBeginImplFrameDeadline();
259
260   // We're drawing now.
261   EXPECT_ACTION_UPDATE_STATE(
262       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
263   state.DidSwapBuffers();
264   state.DidSwapBuffersComplete();
265   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
266
267   EXPECT_FALSE(state.RedrawPending());
268   EXPECT_FALSE(state.CommitPending());
269
270   // Failing the draw makes us require a commit.
271   state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
272   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
273   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
274   EXPECT_ACTION_UPDATE_STATE(
275       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
276   EXPECT_TRUE(state.RedrawPending());
277   EXPECT_TRUE(state.CommitPending());
278 }
279
280 TEST(SchedulerStateMachineTest, TestFailedDrawForMissingHighResNeedsCommit) {
281   SchedulerSettings default_scheduler_settings;
282   StateMachine state(default_scheduler_settings);
283   state.SetCanStart();
284   state.UpdateState(state.NextAction());
285   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
286   state.SetVisible(true);
287   state.SetCanDraw(true);
288   state.SetNeedsRedraw(true);
289   EXPECT_TRUE(state.RedrawPending());
290   EXPECT_TRUE(state.BeginFrameNeeded());
291
292   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
293   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
294   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
295   state.OnBeginImplFrameDeadline();
296   EXPECT_ACTION_UPDATE_STATE(
297       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
298   state.DidSwapBuffers();
299   state.DidSwapBuffersComplete();
300   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
301   EXPECT_FALSE(state.RedrawPending());
302   EXPECT_FALSE(state.CommitPending());
303
304   // Missing high res content requires a commit (but not a redraw)
305   state.DidDrawIfPossibleCompleted(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT);
306   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
307   EXPECT_ACTION_UPDATE_STATE(
308       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
309   EXPECT_FALSE(state.RedrawPending());
310   EXPECT_TRUE(state.CommitPending());
311 }
312
313 TEST(SchedulerStateMachineTest,
314      TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw) {
315   SchedulerSettings default_scheduler_settings;
316   StateMachine state(default_scheduler_settings);
317   state.SetCanStart();
318   state.UpdateState(state.NextAction());
319   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
320
321   state.SetVisible(true);
322   state.SetCanDraw(true);
323   state.SetNeedsRedraw(true);
324   EXPECT_TRUE(state.RedrawPending());
325   EXPECT_TRUE(state.BeginFrameNeeded());
326   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
327   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
328   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
329   state.OnBeginImplFrameDeadline();
330
331   // We're drawing now.
332   EXPECT_ACTION_UPDATE_STATE(
333       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
334   state.DidSwapBuffers();
335   state.DidSwapBuffersComplete();
336   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
337   EXPECT_FALSE(state.RedrawPending());
338   EXPECT_FALSE(state.CommitPending());
339
340   // While still in the same BeginMainFrame callback on the main thread,
341   // set needs redraw again. This should not redraw.
342   state.SetNeedsRedraw(true);
343   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
344
345   // Failing the draw for animation checkerboards makes us require a commit.
346   state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
347   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
348   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
349   EXPECT_ACTION_UPDATE_STATE(
350       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
351   EXPECT_TRUE(state.RedrawPending());
352 }
353
354 TEST(SchedulerStateMachineTest,
355      TestFailedDrawsEventuallyForceDrawAfterNextCommit) {
356   SchedulerSettings scheduler_settings;
357   scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ = 1;
358   StateMachine state(scheduler_settings);
359   state.SetCanStart();
360   state.UpdateState(state.NextAction());
361   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
362   state.SetVisible(true);
363   state.SetCanDraw(true);
364
365   // Start a commit.
366   state.SetNeedsCommit();
367   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
368   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
369   EXPECT_ACTION_UPDATE_STATE(
370       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
371   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
372   EXPECT_TRUE(state.CommitPending());
373
374   // Then initiate a draw.
375   state.SetNeedsRedraw(true);
376   state.OnBeginImplFrameDeadline();
377   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
378   EXPECT_ACTION_UPDATE_STATE(
379       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
380
381   // Fail the draw.
382   state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
383   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
384   EXPECT_TRUE(state.BeginFrameNeeded());
385   EXPECT_TRUE(state.RedrawPending());
386   // But the commit is ongoing.
387   EXPECT_TRUE(state.CommitPending());
388
389   // Finish the commit. Note, we should not yet be forcing a draw, but should
390   // continue the commit as usual.
391   state.NotifyBeginMainFrameStarted();
392   state.NotifyReadyToCommit();
393   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
394   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
395   EXPECT_TRUE(state.RedrawPending());
396
397   // The redraw should be forced at the end of the next BeginImplFrame.
398   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
399   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
400   EXPECT_ACTION_UPDATE_STATE(
401       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
402   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
403   state.OnBeginImplFrameDeadline();
404   EXPECT_ACTION_UPDATE_STATE(
405       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED);
406   state.DidSwapBuffers();
407   state.DidSwapBuffersComplete();
408 }
409
410 TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) {
411   SchedulerSettings scheduler_settings;
412   int draw_limit = 1;
413   scheduler_settings.maximum_number_of_failed_draws_before_draw_is_forced_ =
414       draw_limit;
415   scheduler_settings.impl_side_painting = true;
416   StateMachine state(scheduler_settings);
417   state.SetCanStart();
418   state.UpdateState(state.NextAction());
419   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
420   state.SetVisible(true);
421   state.SetCanDraw(true);
422
423   // Start a commit.
424   state.SetNeedsCommit();
425   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
426   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
427   EXPECT_ACTION_UPDATE_STATE(
428       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
429   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
430   EXPECT_TRUE(state.CommitPending());
431
432   // Then initiate a draw.
433   state.SetNeedsRedraw(true);
434   state.OnBeginImplFrameDeadline();
435   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
436   EXPECT_ACTION_UPDATE_STATE(
437       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
438
439   // Fail the draw enough times to force a redraw,
440   // then once more for good measure.
441   for (int i = 0; i < draw_limit + 1; ++i)
442     state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
443   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
444   EXPECT_TRUE(state.BeginFrameNeeded());
445   EXPECT_TRUE(state.RedrawPending());
446   // But the commit is ongoing.
447   EXPECT_TRUE(state.CommitPending());
448   EXPECT_TRUE(state.ForcedRedrawState() ==
449               SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT);
450
451   state.NotifyBeginMainFrameStarted();
452   state.NotifyReadyToCommit();
453   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
454   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
455   EXPECT_TRUE(state.RedrawPending());
456   EXPECT_FALSE(state.CommitPending());
457
458   // Now force redraw should be in waiting for activation
459   EXPECT_TRUE(state.ForcedRedrawState() ==
460     SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION);
461
462   // After failing additional draws, we should still be in a forced
463   // redraw, but not back in WAITING_FOR_COMMIT.
464   for (int i = 0; i < draw_limit + 1; ++i)
465     state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
466   EXPECT_TRUE(state.RedrawPending());
467   EXPECT_TRUE(state.ForcedRedrawState() ==
468     SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION);
469 }
470
471 TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedInNextBeginImplFrame) {
472   SchedulerSettings default_scheduler_settings;
473   StateMachine state(default_scheduler_settings);
474   state.SetCanStart();
475   state.UpdateState(state.NextAction());
476   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
477   state.SetVisible(true);
478   state.SetCanDraw(true);
479
480   // Start a draw.
481   state.SetNeedsRedraw(true);
482   EXPECT_TRUE(state.BeginFrameNeeded());
483   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
484   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
485   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
486   state.OnBeginImplFrameDeadline();
487   EXPECT_TRUE(state.RedrawPending());
488   EXPECT_ACTION_UPDATE_STATE(
489       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
490
491   // Failing the draw for animation checkerboards makes us require a commit.
492   state.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS);
493   EXPECT_ACTION_UPDATE_STATE(
494       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
495   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
496   EXPECT_TRUE(state.RedrawPending());
497
498   // We should not be trying to draw again now, but we have a commit pending.
499   EXPECT_TRUE(state.BeginFrameNeeded());
500   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
501   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
502   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
503
504   // We should try to draw again at the end of the next BeginImplFrame on
505   // the impl thread.
506   state.OnBeginImplFrameDeadline();
507   EXPECT_ACTION_UPDATE_STATE(
508       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
509   state.DidSwapBuffers();
510   state.DidSwapBuffersComplete();
511   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
512 }
513
514 TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) {
515   SchedulerSettings default_scheduler_settings;
516   StateMachine state(default_scheduler_settings);
517   state.SetCanStart();
518   state.UpdateState(state.NextAction());
519   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
520   state.SetVisible(true);
521   state.SetCanDraw(true);
522   state.SetNeedsRedraw(true);
523
524   // Draw the first frame.
525   EXPECT_TRUE(state.BeginFrameNeeded());
526   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
527   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
528   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
529
530   state.OnBeginImplFrameDeadline();
531   EXPECT_ACTION_UPDATE_STATE(
532       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
533   state.DidSwapBuffers();
534   state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
535   state.DidSwapBuffersComplete();
536   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
537
538   // Before the next BeginImplFrame, set needs redraw again.
539   // This should not redraw until the next BeginImplFrame.
540   state.SetNeedsRedraw(true);
541   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
542
543   // Move to another frame. This should now draw.
544   EXPECT_TRUE(state.BeginFrameNeeded());
545   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
546
547   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
548   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
549
550   state.OnBeginImplFrameDeadline();
551   EXPECT_ACTION_UPDATE_STATE(
552       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
553   state.DidSwapBuffers();
554   state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
555   state.DidSwapBuffersComplete();
556   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
557
558   // We just swapped, so we should proactively request another BeginImplFrame.
559   EXPECT_TRUE(state.BeginFrameNeeded());
560 }
561
562 TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) {
563   SchedulerSettings default_scheduler_settings;
564
565   // When not in BeginImplFrame deadline, or in BeginImplFrame deadline
566   // but not visible, don't draw.
567   size_t num_commit_states =
568       sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState);
569   size_t num_begin_impl_frame_states =
570       sizeof(all_begin_impl_frame_states) /
571       sizeof(SchedulerStateMachine::BeginImplFrameState);
572   for (size_t i = 0; i < num_commit_states; ++i) {
573     for (size_t j = 0; j < num_begin_impl_frame_states; ++j) {
574       StateMachine state(default_scheduler_settings);
575       state.SetCanStart();
576       state.UpdateState(state.NextAction());
577       state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
578       state.SetCommitState(all_commit_states[i]);
579       state.SetBeginImplFrameState(all_begin_impl_frame_states[j]);
580       bool visible =
581           (all_begin_impl_frame_states[j] !=
582            SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
583       state.SetVisible(visible);
584
585       // Case 1: needs_commit=false
586       EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
587                 state.NextAction());
588
589       // Case 2: needs_commit=true
590       state.SetNeedsCommit();
591       EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
592                 state.NextAction())
593           << state.AsValue()->ToString();
594     }
595   }
596
597   // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw
598   // except if we're ready to commit, in which case we expect a commit first.
599   for (size_t i = 0; i < num_commit_states; ++i) {
600     StateMachine state(default_scheduler_settings);
601     state.SetCanStart();
602     state.UpdateState(state.NextAction());
603     state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
604     state.SetCanDraw(true);
605     state.SetCommitState(all_commit_states[i]);
606     state.SetBeginImplFrameState(
607         SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
608
609     state.SetNeedsRedraw(true);
610     state.SetVisible(true);
611
612     SchedulerStateMachine::Action expected_action;
613     if (all_commit_states[i] ==
614         SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT) {
615       expected_action = SchedulerStateMachine::ACTION_COMMIT;
616     } else {
617       expected_action = SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE;
618       EXPECT_EQ(state.NextAction(), SchedulerStateMachine::ACTION_ANIMATE)
619           << state.AsValue()->ToString();
620       state.UpdateState(state.NextAction());
621     }
622
623     // Case 1: needs_commit=false.
624     EXPECT_EQ(state.NextAction(), expected_action)
625         << state.AsValue()->ToString();
626
627     // Case 2: needs_commit=true.
628     state.SetNeedsCommit();
629     EXPECT_EQ(state.NextAction(), expected_action)
630         << state.AsValue()->ToString();
631   }
632 }
633
634 TEST(SchedulerStateMachineTest, TestNoCommitStatesRedrawWhenInvisible) {
635   SchedulerSettings default_scheduler_settings;
636
637   size_t num_commit_states =
638       sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState);
639   for (size_t i = 0; i < num_commit_states; ++i) {
640     // There shouldn't be any drawing regardless of BeginImplFrame.
641     for (size_t j = 0; j < 2; ++j) {
642       StateMachine state(default_scheduler_settings);
643       state.SetCanStart();
644       state.UpdateState(state.NextAction());
645       state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
646       state.SetCommitState(all_commit_states[i]);
647       state.SetVisible(false);
648       state.SetNeedsRedraw(true);
649       if (j == 1) {
650         state.SetBeginImplFrameState(
651             SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE);
652       }
653
654       // Case 1: needs_commit=false.
655       EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
656                 state.NextAction());
657
658       // Case 2: needs_commit=true.
659       state.SetNeedsCommit();
660       EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
661                 state.NextAction())
662           << state.AsValue()->ToString();
663     }
664   }
665 }
666
667 TEST(SchedulerStateMachineTest, TestCanRedraw_StopsDraw) {
668   SchedulerSettings default_scheduler_settings;
669
670   size_t num_commit_states =
671       sizeof(all_commit_states) / sizeof(SchedulerStateMachine::CommitState);
672   for (size_t i = 0; i < num_commit_states; ++i) {
673     // There shouldn't be any drawing regardless of BeginImplFrame.
674     for (size_t j = 0; j < 2; ++j) {
675       StateMachine state(default_scheduler_settings);
676       state.SetCanStart();
677       state.UpdateState(state.NextAction());
678       state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
679       state.SetCommitState(all_commit_states[i]);
680       state.SetVisible(false);
681       state.SetNeedsRedraw(true);
682       if (j == 1)
683         state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
684
685       state.SetCanDraw(false);
686       EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
687                 state.NextAction());
688     }
689   }
690 }
691
692 TEST(SchedulerStateMachineTest,
693      TestCanRedrawWithWaitingForFirstDrawMakesProgress) {
694   SchedulerSettings default_scheduler_settings;
695   StateMachine state(default_scheduler_settings);
696   state.SetCanStart();
697   state.UpdateState(state.NextAction());
698   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
699
700   state.SetActiveTreeNeedsFirstDraw(true);
701   state.SetNeedsCommit();
702   state.SetNeedsRedraw(true);
703   state.SetVisible(true);
704   state.SetCanDraw(false);
705   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
706   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
707   EXPECT_ACTION_UPDATE_STATE(
708       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
709   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
710   state.NotifyBeginMainFrameStarted();
711   state.NotifyReadyToCommit();
712   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
713   state.OnBeginImplFrameDeadline();
714   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
715   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
716 }
717
718 TEST(SchedulerStateMachineTest, TestSetNeedsCommitIsNotLost) {
719   SchedulerSettings scheduler_settings;
720   StateMachine state(scheduler_settings);
721   state.SetCanStart();
722   state.UpdateState(state.NextAction());
723   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
724   state.SetNeedsCommit();
725   state.SetVisible(true);
726   state.SetCanDraw(true);
727
728   EXPECT_TRUE(state.BeginFrameNeeded());
729
730   // Begin the frame.
731   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
732   EXPECT_ACTION_UPDATE_STATE(
733       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
734   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
735             state.CommitState());
736
737   // Now, while the frame is in progress, set another commit.
738   state.SetNeedsCommit();
739   EXPECT_TRUE(state.NeedsCommit());
740
741   // Let the frame finish.
742   state.NotifyBeginMainFrameStarted();
743   state.NotifyReadyToCommit();
744   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
745             state.CommitState());
746
747   // Expect to commit regardless of BeginImplFrame state.
748   EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
749             state.begin_impl_frame_state());
750   EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
751
752   state.OnBeginImplFrameDeadlinePending();
753   EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
754             state.begin_impl_frame_state());
755   EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
756
757   state.OnBeginImplFrameDeadline();
758   EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE,
759             state.begin_impl_frame_state());
760   EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
761
762   state.OnBeginImplFrameIdle();
763   EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
764             state.begin_impl_frame_state());
765   EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
766
767   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
768   EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
769             state.begin_impl_frame_state());
770   EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
771
772   // Finish the commit, then make sure we start the next commit immediately
773   // and draw on the next BeginImplFrame.
774   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
775   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
776   EXPECT_ACTION_UPDATE_STATE(
777       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
778   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
779
780   state.OnBeginImplFrameDeadline();
781
782   EXPECT_TRUE(state.active_tree_needs_first_draw());
783   EXPECT_ACTION_UPDATE_STATE(
784       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
785   state.DidSwapBuffers();
786   state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
787   state.DidSwapBuffersComplete();
788   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
789 }
790
791 TEST(SchedulerStateMachineTest, TestFullCycle) {
792   SchedulerSettings default_scheduler_settings;
793   StateMachine state(default_scheduler_settings);
794   state.SetCanStart();
795   state.UpdateState(state.NextAction());
796   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
797   state.SetVisible(true);
798   state.SetCanDraw(true);
799
800   // Start clean and set commit.
801   state.SetNeedsCommit();
802
803   // Begin the frame.
804   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
805   EXPECT_ACTION_UPDATE_STATE(
806       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
807   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
808             state.CommitState());
809   EXPECT_FALSE(state.NeedsCommit());
810   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
811
812   // Tell the scheduler the frame finished.
813   state.NotifyBeginMainFrameStarted();
814   state.NotifyReadyToCommit();
815   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
816             state.CommitState());
817
818   // Commit.
819   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
820   EXPECT_TRUE(state.active_tree_needs_first_draw());
821   EXPECT_TRUE(state.needs_redraw());
822
823   // Expect to do nothing until BeginImplFrame deadline
824   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
825
826   // At BeginImplFrame deadline, draw.
827   state.OnBeginImplFrameDeadline();
828   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
829   EXPECT_ACTION_UPDATE_STATE(
830       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
831   state.DidSwapBuffers();
832   state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
833   state.DidSwapBuffersComplete();
834
835   // Should be synchronized, no draw needed, no action needed.
836   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
837   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
838   EXPECT_FALSE(state.needs_redraw());
839 }
840
841 TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) {
842   SchedulerSettings default_scheduler_settings;
843   StateMachine state(default_scheduler_settings);
844   state.SetCanStart();
845   state.UpdateState(state.NextAction());
846   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
847   state.SetVisible(true);
848   state.SetCanDraw(true);
849
850   // Start clean and set commit.
851   state.SetNeedsCommit();
852
853   // Begin the frame.
854   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
855   EXPECT_ACTION_UPDATE_STATE(
856       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
857   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
858             state.CommitState());
859   EXPECT_FALSE(state.NeedsCommit());
860   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
861
862   // Request another commit while the commit is in flight.
863   state.SetNeedsCommit();
864   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
865
866   // Tell the scheduler the frame finished.
867   state.NotifyBeginMainFrameStarted();
868   state.NotifyReadyToCommit();
869   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
870             state.CommitState());
871
872   // First commit.
873   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
874   EXPECT_TRUE(state.active_tree_needs_first_draw());
875   EXPECT_TRUE(state.needs_redraw());
876
877   // Expect to do nothing until BeginImplFrame deadline.
878   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
879
880   // At BeginImplFrame deadline, draw.
881   state.OnBeginImplFrameDeadline();
882   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
883   EXPECT_ACTION_UPDATE_STATE(
884       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
885   state.DidSwapBuffers();
886   state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
887   state.DidSwapBuffersComplete();
888
889   // Should be synchronized, no draw needed, no action needed.
890   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
891   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
892   EXPECT_FALSE(state.needs_redraw());
893
894   // Next BeginImplFrame should initiate second commit.
895   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
896   EXPECT_ACTION_UPDATE_STATE(
897       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
898 }
899
900 TEST(SchedulerStateMachineTest, TestRequestCommitInvisible) {
901   SchedulerSettings default_scheduler_settings;
902   StateMachine state(default_scheduler_settings);
903   state.SetCanStart();
904   state.UpdateState(state.NextAction());
905   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
906   state.SetNeedsCommit();
907   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
908 }
909
910 TEST(SchedulerStateMachineTest, TestGoesInvisibleBeforeFinishCommit) {
911   SchedulerSettings default_scheduler_settings;
912   StateMachine state(default_scheduler_settings);
913   state.SetCanStart();
914   state.UpdateState(state.NextAction());
915   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
916   state.SetVisible(true);
917   state.SetCanDraw(true);
918
919   // Start clean and set commit.
920   state.SetNeedsCommit();
921
922   // Begin the frame while visible.
923   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
924   EXPECT_ACTION_UPDATE_STATE(
925       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
926   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
927             state.CommitState());
928   EXPECT_FALSE(state.NeedsCommit());
929   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
930
931   // Become invisible and abort BeginMainFrame.
932   state.SetVisible(false);
933   state.BeginMainFrameAborted(false);
934
935   // We should now be back in the idle state as if we never started the frame.
936   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
937   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
938
939   // We shouldn't do anything on the BeginImplFrame deadline.
940   state.OnBeginImplFrameDeadline();
941   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
942
943   // Become visible again.
944   state.SetVisible(true);
945
946   // Although we have aborted on this frame and haven't cancelled the commit
947   // (i.e. need another), don't send another BeginMainFrame yet.
948   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
949   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
950   EXPECT_TRUE(state.NeedsCommit());
951
952   // Start a new frame.
953   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
954   EXPECT_ACTION_UPDATE_STATE(
955       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
956
957   // We should be starting the commit now.
958   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
959             state.CommitState());
960   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
961 }
962
963 TEST(SchedulerStateMachineTest, AbortBeginMainFrameAndCancelCommit) {
964   SchedulerSettings default_scheduler_settings;
965   StateMachine state(default_scheduler_settings);
966   state.SetCanStart();
967   state.UpdateState(state.NextAction());
968   state.DidCreateAndInitializeOutputSurface();
969   state.SetVisible(true);
970   state.SetCanDraw(true);
971
972   // Get into a begin frame / commit state.
973   state.SetNeedsCommit();
974
975   EXPECT_ACTION_UPDATE_STATE(
976       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
977   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
978             state.CommitState());
979   EXPECT_FALSE(state.NeedsCommit());
980   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
981
982   // Abort the commit, cancelling future commits.
983   state.BeginMainFrameAborted(true);
984
985   // Verify that another commit doesn't start on the same frame.
986   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
987   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
988   EXPECT_FALSE(state.NeedsCommit());
989
990   // Start a new frame; draw because this is the first frame since output
991   // surface init'd.
992   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
993   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
994   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
995   state.OnBeginImplFrameDeadline();
996   EXPECT_ACTION_UPDATE_STATE(
997       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
998   state.DidSwapBuffers();
999   state.DidSwapBuffersComplete();
1000
1001   // Verify another commit doesn't start on another frame either.
1002   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1003   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1004   EXPECT_FALSE(state.NeedsCommit());
1005
1006   // Verify another commit can start if requested, though.
1007   state.SetNeedsCommit();
1008   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1009   EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
1010             state.NextAction());
1011 }
1012
1013 TEST(SchedulerStateMachineTest,
1014      AbortBeginMainFrameAndCancelCommitWhenInvisible) {
1015   SchedulerSettings default_scheduler_settings;
1016   StateMachine state(default_scheduler_settings);
1017   state.SetCanStart();
1018   state.UpdateState(state.NextAction());
1019   state.DidCreateAndInitializeOutputSurface();
1020   state.SetVisible(true);
1021   state.SetCanDraw(true);
1022
1023   // Get into a begin frame / commit state.
1024   state.SetNeedsCommit();
1025
1026   EXPECT_ACTION_UPDATE_STATE(
1027       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1028   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
1029             state.CommitState());
1030   EXPECT_FALSE(state.NeedsCommit());
1031   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1032
1033   // Become invisible and abort BeginMainFrame.
1034   state.SetVisible(false);
1035   state.BeginMainFrameAborted(true);
1036
1037   // Verify that another commit doesn't start on the same frame.
1038   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1039   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1040   EXPECT_FALSE(state.NeedsCommit());
1041
1042   // Become visible and start a new frame.
1043   state.SetVisible(true);
1044   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1045   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1046   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1047
1048   // Draw because this is the first frame since output surface init'd.
1049   state.OnBeginImplFrameDeadline();
1050   EXPECT_ACTION_UPDATE_STATE(
1051       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1052   state.DidSwapBuffers();
1053   state.DidSwapBuffersComplete();
1054
1055   // Verify another commit doesn't start on another frame either.
1056   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1057   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1058   EXPECT_FALSE(state.NeedsCommit());
1059
1060   // Verify another commit can start if requested, though.
1061   state.SetNeedsCommit();
1062   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1063   EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
1064             state.NextAction());
1065 }
1066
1067 TEST(SchedulerStateMachineTest,
1068      AbortBeginMainFrameAndRequestCommitWhenInvisible) {
1069   SchedulerSettings default_scheduler_settings;
1070   StateMachine state(default_scheduler_settings);
1071   state.SetCanStart();
1072   state.UpdateState(state.NextAction());
1073   state.DidCreateAndInitializeOutputSurface();
1074   state.SetVisible(true);
1075   state.SetCanDraw(true);
1076
1077   // Get into a begin frame / commit state.
1078   state.SetNeedsCommit();
1079
1080   EXPECT_ACTION_UPDATE_STATE(
1081       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1082   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
1083             state.CommitState());
1084   EXPECT_FALSE(state.NeedsCommit());
1085   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1086
1087   // Become invisible and abort BeginMainFrame.
1088   state.SetVisible(false);
1089   state.BeginMainFrameAborted(true);
1090
1091   // Verify that another commit doesn't start on the same frame.
1092   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1093   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1094   EXPECT_FALSE(state.NeedsCommit());
1095
1096   // Asking for a commit while not visible won't make it happen.
1097   state.SetNeedsCommit();
1098   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1099   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1100   EXPECT_TRUE(state.NeedsCommit());
1101
1102   // Become visible but nothing happens until the next frame.
1103   state.SetVisible(true);
1104   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1105   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1106   EXPECT_TRUE(state.NeedsCommit());
1107
1108   // We should get that commit when we begin the next frame.
1109   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1110   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1111   EXPECT_ACTION_UPDATE_STATE(
1112       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1113 }
1114
1115 TEST(SchedulerStateMachineTest,
1116      AbortBeginMainFrameAndRequestCommitAndBeginImplFrameWhenInvisible) {
1117   SchedulerSettings default_scheduler_settings;
1118   StateMachine state(default_scheduler_settings);
1119   state.SetCanStart();
1120   state.UpdateState(state.NextAction());
1121   state.DidCreateAndInitializeOutputSurface();
1122   state.SetVisible(true);
1123   state.SetCanDraw(true);
1124
1125   // Get into a begin frame / commit state.
1126   state.SetNeedsCommit();
1127
1128   EXPECT_ACTION_UPDATE_STATE(
1129       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1130   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
1131             state.CommitState());
1132   EXPECT_FALSE(state.NeedsCommit());
1133   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1134
1135   // Become invisible and abort BeginMainFrame.
1136   state.SetVisible(false);
1137   state.BeginMainFrameAborted(true);
1138
1139   // Asking for a commit while not visible won't make it happen.
1140   state.SetNeedsCommit();
1141   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1142   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1143   EXPECT_TRUE(state.NeedsCommit());
1144
1145   // Begin a frame when not visible, the scheduler animates but does not commit.
1146   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1147   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1148   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1149   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1150   EXPECT_TRUE(state.NeedsCommit());
1151
1152   // Become visible and the requested commit happens immediately.
1153   state.SetVisible(true);
1154   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1155   EXPECT_ACTION_UPDATE_STATE(
1156       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1157 }
1158
1159 TEST(SchedulerStateMachineTest, TestFirstContextCreation) {
1160   SchedulerSettings default_scheduler_settings;
1161   StateMachine state(default_scheduler_settings);
1162   state.SetCanStart();
1163   state.SetVisible(true);
1164   state.SetCanDraw(true);
1165
1166   EXPECT_ACTION_UPDATE_STATE(
1167       SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1168   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1169   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1170
1171   // Check that the first init does not SetNeedsCommit.
1172   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1173   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1174   state.OnBeginImplFrameDeadline();
1175   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1176
1177   // Check that a needs commit initiates a BeginMainFrame.
1178   state.SetNeedsCommit();
1179   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1180   EXPECT_ACTION_UPDATE_STATE(
1181       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1182 }
1183
1184 TEST(SchedulerStateMachineTest, TestContextLostWhenCompletelyIdle) {
1185   SchedulerSettings default_scheduler_settings;
1186   StateMachine state(default_scheduler_settings);
1187   state.SetCanStart();
1188   state.UpdateState(state.NextAction());
1189   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1190
1191   state.SetVisible(true);
1192   state.SetCanDraw(true);
1193
1194   EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1195             state.NextAction());
1196   state.DidLoseOutputSurface();
1197
1198   EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1199             state.NextAction());
1200   state.UpdateState(state.NextAction());
1201
1202   // Once context recreation begins, nothing should happen.
1203   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1204
1205   // Recreate the context.
1206   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1207
1208   // When the context is recreated, we should begin a commit.
1209   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1210   EXPECT_ACTION_UPDATE_STATE(
1211       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1212 }
1213
1214 TEST(SchedulerStateMachineTest,
1215      TestContextLostWhenIdleAndCommitRequestedWhileRecreating) {
1216   SchedulerSettings default_scheduler_settings;
1217   StateMachine state(default_scheduler_settings);
1218   state.SetCanStart();
1219   state.UpdateState(state.NextAction());
1220   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1221   state.SetVisible(true);
1222   state.SetCanDraw(true);
1223
1224   EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1225             state.NextAction());
1226   state.DidLoseOutputSurface();
1227
1228   EXPECT_ACTION_UPDATE_STATE(
1229       SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1230   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1231
1232   // Once context recreation begins, nothing should happen.
1233   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1234   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1235   state.OnBeginImplFrameDeadline();
1236   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1237
1238   // While context is recreating, commits shouldn't begin.
1239   state.SetNeedsCommit();
1240   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1241   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1242   state.OnBeginImplFrameDeadline();
1243   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1244
1245   // Recreate the context
1246   state.DidCreateAndInitializeOutputSurface();
1247   EXPECT_FALSE(state.RedrawPending());
1248
1249   // When the context is recreated, we should begin a commit
1250   EXPECT_ACTION_UPDATE_STATE(
1251       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1252   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1253   EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
1254             state.CommitState());
1255
1256   state.NotifyBeginMainFrameStarted();
1257   state.NotifyReadyToCommit();
1258   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1259   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1260   // Finishing the first commit after initializing an output surface should
1261   // automatically cause a redraw.
1262   EXPECT_TRUE(state.RedrawPending());
1263
1264   // Once the context is recreated, whether we draw should be based on
1265   // SetCanDraw.
1266   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1267   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1268   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1269   state.OnBeginImplFrameDeadline();
1270   EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
1271             state.NextAction());
1272   state.SetCanDraw(false);
1273   EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT,
1274             state.NextAction());
1275   state.SetCanDraw(true);
1276   EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
1277             state.NextAction());
1278 }
1279
1280 TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) {
1281   SchedulerSettings scheduler_settings;
1282   StateMachine state(scheduler_settings);
1283   state.SetCanStart();
1284   state.UpdateState(state.NextAction());
1285   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1286   state.SetVisible(true);
1287   state.SetCanDraw(true);
1288
1289   // Get a commit in flight.
1290   state.SetNeedsCommit();
1291
1292   // Set damage and expect a draw.
1293   state.SetNeedsRedraw(true);
1294   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1295   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1296   EXPECT_ACTION_UPDATE_STATE(
1297       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1298   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1299   state.OnBeginImplFrameDeadline();
1300   EXPECT_ACTION_UPDATE_STATE(
1301       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1302   state.DidSwapBuffers();
1303   state.DidSwapBuffersComplete();
1304   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1305
1306   // Cause a lost context while the BeginMainFrame is in flight.
1307   state.DidLoseOutputSurface();
1308
1309   // Ask for another draw. Expect nothing happens.
1310   state.SetNeedsRedraw(true);
1311   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1312
1313   // Finish the frame, and commit.
1314   state.NotifyBeginMainFrameStarted();
1315   state.NotifyReadyToCommit();
1316   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1317
1318   // We will abort the draw when the output surface is lost if we are
1319   // waiting for the first draw to unblock the main thread.
1320   EXPECT_TRUE(state.active_tree_needs_first_draw());
1321   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1322
1323   // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1324   EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
1325             state.begin_impl_frame_state());
1326   EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1327             state.NextAction());
1328
1329   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1330   EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
1331             state.begin_impl_frame_state());
1332   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1333
1334   state.OnBeginImplFrameDeadlinePending();
1335   EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
1336             state.begin_impl_frame_state());
1337   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1338
1339   state.OnBeginImplFrameDeadline();
1340   EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE,
1341             state.begin_impl_frame_state());
1342   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1343 }
1344
1345 TEST(SchedulerStateMachineTest,
1346      TestContextLostWhileCommitInProgressAndAnotherCommitRequested) {
1347   SchedulerSettings scheduler_settings;
1348   StateMachine state(scheduler_settings);
1349   state.SetCanStart();
1350   state.UpdateState(state.NextAction());
1351   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1352   state.SetVisible(true);
1353   state.SetCanDraw(true);
1354
1355   // Get a commit in flight.
1356   state.SetNeedsCommit();
1357   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1358
1359   // Set damage and expect a draw.
1360   state.SetNeedsRedraw(true);
1361   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1362   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1363   EXPECT_ACTION_UPDATE_STATE(
1364       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1365   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1366   state.OnBeginImplFrameDeadline();
1367   EXPECT_ACTION_UPDATE_STATE(
1368       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1369   state.DidSwapBuffers();
1370   state.DidSwapBuffersComplete();
1371   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1372
1373   // Cause a lost context while the BeginMainFrame is in flight.
1374   state.DidLoseOutputSurface();
1375
1376   // Ask for another draw and also set needs commit. Expect nothing happens.
1377   state.SetNeedsRedraw(true);
1378   state.SetNeedsCommit();
1379   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1380
1381   // Finish the frame, and commit.
1382   state.NotifyBeginMainFrameStarted();
1383   state.NotifyReadyToCommit();
1384   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1385   EXPECT_TRUE(state.active_tree_needs_first_draw());
1386
1387   // Because the output surface is missing, we expect the draw to abort.
1388   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1389
1390   // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1391   EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
1392             state.begin_impl_frame_state());
1393   EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1394             state.NextAction());
1395
1396   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1397   EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
1398             state.begin_impl_frame_state());
1399   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1400
1401   state.OnBeginImplFrameDeadlinePending();
1402   EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
1403             state.begin_impl_frame_state());
1404   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1405
1406   state.OnBeginImplFrameDeadline();
1407   EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE,
1408             state.begin_impl_frame_state());
1409   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1410
1411   state.OnBeginImplFrameIdle();
1412   EXPECT_ACTION_UPDATE_STATE(
1413       SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1414
1415   // After we get a new output surface, the commit flow should start.
1416   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1417   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1418   EXPECT_ACTION_UPDATE_STATE(
1419       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1420   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1421   state.NotifyBeginMainFrameStarted();
1422   state.NotifyReadyToCommit();
1423   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1424   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1425   state.OnBeginImplFrameDeadline();
1426   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1427   EXPECT_ACTION_UPDATE_STATE(
1428       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1429   state.DidSwapBuffers();
1430   state.DidSwapBuffersComplete();
1431   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1432 }
1433
1434 TEST(SchedulerStateMachineTest, DontDrawBeforeCommitAfterLostOutputSurface) {
1435   SchedulerSettings default_scheduler_settings;
1436   StateMachine state(default_scheduler_settings);
1437   state.SetCanStart();
1438   state.UpdateState(state.NextAction());
1439   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1440   state.SetVisible(true);
1441   state.SetCanDraw(true);
1442
1443   state.SetNeedsRedraw(true);
1444
1445   // Cause a lost output surface, and restore it.
1446   state.DidLoseOutputSurface();
1447   EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1448             state.NextAction());
1449   state.UpdateState(state.NextAction());
1450   state.DidCreateAndInitializeOutputSurface();
1451
1452   EXPECT_FALSE(state.RedrawPending());
1453   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1454   EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
1455             state.NextAction());
1456 }
1457
1458 TEST(SchedulerStateMachineTest,
1459      TestPendingActivationsShouldBeForcedAfterLostOutputSurface) {
1460   SchedulerSettings settings;
1461   settings.impl_side_painting = true;
1462   StateMachine state(settings);
1463   state.SetCanStart();
1464   state.UpdateState(state.NextAction());
1465   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1466   state.SetVisible(true);
1467   state.SetCanDraw(true);
1468
1469   state.SetCommitState(
1470       SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1471
1472   // Cause a lost context.
1473   state.DidLoseOutputSurface();
1474
1475   state.NotifyBeginMainFrameStarted();
1476   state.NotifyReadyToCommit();
1477   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1478
1479   EXPECT_TRUE(state.PendingActivationsShouldBeForced());
1480   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1481
1482   EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1483   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1484 }
1485
1486 TEST(SchedulerStateMachineTest, TestNoBeginMainFrameWhenInvisible) {
1487   SchedulerSettings default_scheduler_settings;
1488   StateMachine state(default_scheduler_settings);
1489   state.SetCanStart();
1490   state.UpdateState(state.NextAction());
1491   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1492   state.SetVisible(false);
1493   state.SetNeedsCommit();
1494   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1495 }
1496
1497 TEST(SchedulerStateMachineTest, TestFinishCommitWhenCommitInProgress) {
1498   SchedulerSettings default_scheduler_settings;
1499   StateMachine state(default_scheduler_settings);
1500   state.SetCanStart();
1501   state.UpdateState(state.NextAction());
1502   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1503   state.SetVisible(false);
1504   state.SetCommitState(
1505       SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1506   state.SetNeedsCommit();
1507
1508   state.NotifyBeginMainFrameStarted();
1509   state.NotifyReadyToCommit();
1510   EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
1511   state.UpdateState(state.NextAction());
1512
1513   EXPECT_TRUE(state.active_tree_needs_first_draw());
1514   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1515 }
1516
1517 TEST(SchedulerStateMachineTest, TestInitialActionsWhenContextLost) {
1518   SchedulerSettings default_scheduler_settings;
1519   StateMachine state(default_scheduler_settings);
1520   state.SetCanStart();
1521   state.UpdateState(state.NextAction());
1522   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1523   state.SetVisible(true);
1524   state.SetCanDraw(true);
1525   state.SetNeedsCommit();
1526   state.DidLoseOutputSurface();
1527
1528   // When we are visible, we normally want to begin output surface creation
1529   // as soon as possible.
1530   EXPECT_ACTION_UPDATE_STATE(
1531       SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1532
1533   state.DidCreateAndInitializeOutputSurface();
1534   EXPECT_EQ(state.output_surface_state(),
1535             SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT);
1536
1537   // We should not send a BeginMainFrame when we are invisible, even if we've
1538   // lost the output surface and are trying to get the first commit, since the
1539   // main thread will just abort anyway.
1540   state.SetVisible(false);
1541   EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction())
1542       << state.AsValue()->ToString();
1543 }
1544
1545 TEST(SchedulerStateMachineTest, ReportIfNotDrawing) {
1546   SchedulerSettings default_scheduler_settings;
1547   StateMachine state(default_scheduler_settings);
1548   state.SetCanStart();
1549   state.UpdateState(state.NextAction());
1550   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1551
1552   state.SetCanDraw(true);
1553   state.SetVisible(true);
1554   EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
1555
1556   state.SetCanDraw(false);
1557   state.SetVisible(true);
1558   EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1559
1560   state.SetCanDraw(true);
1561   state.SetVisible(false);
1562   EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1563
1564   state.SetCanDraw(false);
1565   state.SetVisible(false);
1566   EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1567
1568   state.SetCanDraw(true);
1569   state.SetVisible(true);
1570   EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
1571 }
1572
1573 TEST(SchedulerStateMachineTest, TestTriggerDeadlineEarlyAfterAbortedCommit) {
1574   SchedulerSettings settings;
1575   settings.impl_side_painting = true;
1576   StateMachine state(settings);
1577   state.SetCanStart();
1578   state.UpdateState(state.NextAction());
1579   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1580   state.SetVisible(true);
1581   state.SetCanDraw(true);
1582
1583   // This test mirrors what happens during the first frame of a scroll gesture.
1584   // First we get the input event and a BeginFrame.
1585   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1586
1587   // As a response the compositor requests a redraw and a commit to tell the
1588   // main thread about the new scroll offset.
1589   state.SetNeedsRedraw(true);
1590   state.SetNeedsCommit();
1591
1592   // We should start the commit normally.
1593   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1594   EXPECT_ACTION_UPDATE_STATE(
1595       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1596   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1597
1598   // Since only the scroll offset changed, the main thread will abort the
1599   // commit.
1600   state.BeginMainFrameAborted(true);
1601
1602   // Since the commit was aborted, we should draw right away instead of waiting
1603   // for the deadline.
1604   EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
1605 }
1606
1607 void FinishPreviousCommitAndDrawWithoutExitingDeadline(
1608     StateMachine* state_ptr) {
1609   // Gross, but allows us to use macros below.
1610   StateMachine& state = *state_ptr;
1611
1612   state.NotifyBeginMainFrameStarted();
1613   state.NotifyReadyToCommit();
1614   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1615   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1616   state.NotifyReadyToActivate();
1617   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1618   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1619
1620   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1621   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1622   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1623
1624   EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
1625   state.OnBeginImplFrameDeadline();
1626   EXPECT_ACTION_UPDATE_STATE(
1627       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1628   state.DidSwapBuffers();
1629 }
1630
1631 TEST(SchedulerStateMachineTest, TestImplLatencyTakesPriority) {
1632   SchedulerSettings settings;
1633   settings.impl_side_painting = true;
1634   StateMachine state(settings);
1635   state.SetCanStart();
1636   state.UpdateState(state.NextAction());
1637   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1638   state.SetVisible(true);
1639   state.SetCanDraw(true);
1640
1641   // This test ensures that impl-draws are prioritized over main thread updates
1642   // in prefer impl latency mode.
1643   state.SetNeedsRedraw(true);
1644   state.SetNeedsCommit();
1645   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1646   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1647   EXPECT_ACTION_UPDATE_STATE(
1648       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1649   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1650
1651   // Verify the deadline is not triggered early until we enter
1652   // prefer impl latency mode.
1653   EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
1654   state.SetImplLatencyTakesPriority(true);
1655   EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
1656
1657   // Trigger the deadline.
1658   state.OnBeginImplFrameDeadline();
1659   EXPECT_ACTION_UPDATE_STATE(
1660       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1661   state.DidSwapBuffers();
1662   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1663   state.DidSwapBuffersComplete();
1664
1665   // Request a new commit and finish the previous one.
1666   state.SetNeedsCommit();
1667   FinishPreviousCommitAndDrawWithoutExitingDeadline(&state);
1668   EXPECT_ACTION_UPDATE_STATE(
1669       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1670   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1671   state.DidSwapBuffersComplete();
1672   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1673
1674   // Finish the previous commit and draw it.
1675   FinishPreviousCommitAndDrawWithoutExitingDeadline(&state);
1676   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1677
1678   // Verify we do not send another BeginMainFrame if was are swap throttled
1679   // and did not just swap.
1680   state.SetNeedsCommit();
1681   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1682   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1683   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1684   EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
1685   state.OnBeginImplFrameDeadline();
1686   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1687 }
1688
1689 TEST(SchedulerStateMachineTest, TestTriggerDeadlineEarlyOnLostOutputSurface) {
1690   SchedulerSettings default_scheduler_settings;
1691   StateMachine state(default_scheduler_settings);
1692   state.SetCanStart();
1693   state.UpdateState(state.NextAction());
1694   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1695   state.SetVisible(true);
1696   state.SetCanDraw(true);
1697
1698   state.SetNeedsCommit();
1699
1700   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1701   EXPECT_ACTION_UPDATE_STATE(
1702       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1703   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1704   EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
1705
1706   state.DidLoseOutputSurface();
1707   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1708   // The deadline should be triggered immediately when output surface is lost.
1709   EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
1710 }
1711
1712 TEST(SchedulerStateMachineTest, TestSetNeedsAnimate) {
1713   SchedulerSettings settings;
1714   settings.impl_side_painting = true;
1715   StateMachine state(settings);
1716   state.SetCanStart();
1717   state.UpdateState(state.NextAction());
1718   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1719   state.SetVisible(true);
1720   state.SetCanDraw(true);
1721
1722   // Test requesting an animation that, when run, causes us to draw.
1723   state.SetNeedsAnimate();
1724   EXPECT_TRUE(state.BeginFrameNeeded());
1725   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1726
1727   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1728   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1729
1730   state.OnBeginImplFrameDeadlinePending();
1731   state.OnBeginImplFrameDeadline();
1732   EXPECT_ACTION_UPDATE_STATE(
1733       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1734 }
1735
1736 TEST(SchedulerStateMachineTest, TestAnimateBeforeCommit) {
1737   SchedulerSettings settings;
1738   settings.impl_side_painting = true;
1739   StateMachine state(settings);
1740   state.SetCanStart();
1741   state.UpdateState(state.NextAction());
1742   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1743   state.SetVisible(true);
1744   state.SetCanDraw(true);
1745
1746   // Check that animations are updated before we start a commit.
1747   state.SetNeedsAnimate();
1748   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1749   state.SetNeedsCommit();
1750   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1751   EXPECT_TRUE(state.BeginFrameNeeded());
1752
1753   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1754   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1755   EXPECT_ACTION_UPDATE_STATE(
1756       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1757
1758   state.OnBeginImplFrameDeadlinePending();
1759   state.OnBeginImplFrameDeadline();
1760   EXPECT_ACTION_UPDATE_STATE(
1761       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1762 }
1763
1764 TEST(SchedulerStateMachineTest, TestAnimateAfterCommitBeforeDraw) {
1765   SchedulerSettings settings;
1766   settings.impl_side_painting = true;
1767   StateMachine state(settings);
1768   state.SetCanStart();
1769   state.UpdateState(state.NextAction());
1770   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1771   state.SetVisible(true);
1772   state.SetCanDraw(true);
1773
1774   // Check that animations are updated before we start a commit.
1775   state.SetNeedsAnimate();
1776   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1777   state.SetNeedsCommit();
1778   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1779   EXPECT_TRUE(state.BeginFrameNeeded());
1780
1781   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1782   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1783   EXPECT_ACTION_UPDATE_STATE(
1784       SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1785
1786   state.NotifyBeginMainFrameStarted();
1787   state.NotifyReadyToCommit();
1788   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1789
1790   state.OnBeginImplFrameDeadlinePending();
1791   state.OnBeginImplFrameDeadline();
1792   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1793   EXPECT_ACTION_UPDATE_STATE(
1794       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1795 }
1796
1797 TEST(SchedulerStateMachineTest, TestSetNeedsAnimateAfterAnimate) {
1798   SchedulerSettings settings;
1799   settings.impl_side_painting = true;
1800   StateMachine state(settings);
1801   state.SetCanStart();
1802   state.UpdateState(state.NextAction());
1803   state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1804   state.SetVisible(true);
1805   state.SetCanDraw(true);
1806
1807   // Test requesting an animation after we have already animated during this
1808   // frame.
1809   state.SetNeedsRedraw(true);
1810   EXPECT_TRUE(state.BeginFrameNeeded());
1811   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1812
1813   state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1814   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1815
1816   state.SetNeedsAnimate();
1817   EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1818
1819   state.OnBeginImplFrameDeadline();
1820   EXPECT_ACTION_UPDATE_STATE(
1821       SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1822 }
1823
1824 }  // namespace
1825 }  // namespace cc