Explicitly add python-numpy dependency to install-build-deps.
[chromium-blink-merge.git] / cc / scheduler / scheduler_state_machine_unittest.cc
blob85160ed1c482f5e0cd89cc881e542d06f3312a69
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.
5 #include "cc/scheduler/scheduler_state_machine.h"
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"
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(); \
32 namespace cc {
34 namespace {
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, };
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};
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) {}
55 void CreateAndInitializeOutputSurfaceWithActivatedCommit() {
56 DidCreateAndInitializeOutputSurface();
57 output_surface_state_ = OUTPUT_SURFACE_ACTIVE;
60 void SetCommitState(CommitState cs) { commit_state_ = cs; }
61 CommitState CommitState() const { return commit_state_; }
63 ForcedRedrawOnTimeoutState ForcedRedrawState() const {
64 return forced_redraw_state_;
67 void SetBeginImplFrameState(BeginImplFrameState bifs) {
68 begin_impl_frame_state_ = bifs;
71 BeginImplFrameState begin_impl_frame_state() const {
72 return begin_impl_frame_state_;
75 OutputSurfaceState output_surface_state() const {
76 return output_surface_state_;
79 bool NeedsCommit() const { return needs_commit_; }
81 void SetNeedsRedraw(bool b) { needs_redraw_ = b; }
83 void SetNeedsForcedRedrawForTimeout(bool b) {
84 forced_redraw_state_ = FORCED_REDRAW_STATE_WAITING_FOR_COMMIT;
85 active_tree_needs_first_draw_ = true;
87 bool NeedsForcedRedrawForTimeout() const {
88 return forced_redraw_state_ != FORCED_REDRAW_STATE_IDLE;
91 void SetActiveTreeNeedsFirstDraw(bool needs_first_draw) {
92 active_tree_needs_first_draw_ = needs_first_draw;
95 bool CanDraw() const { return can_draw_; }
96 bool Visible() const { return visible_; }
98 bool PendingActivationsShouldBeForced() const {
99 return SchedulerStateMachine::PendingActivationsShouldBeForced();
102 void SetHasPendingTree(bool has_pending_tree) {
103 has_pending_tree_ = has_pending_tree;
107 TEST(SchedulerStateMachineTest, TestNextActionBeginsMainFrameIfNeeded) {
108 SchedulerSettings default_scheduler_settings;
110 // If no commit needed, do nothing.
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);
121 EXPECT_FALSE(state.BeginFrameNeeded());
123 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
124 EXPECT_FALSE(state.BeginFrameNeeded());
125 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
127 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
128 state.OnBeginImplFrameDeadline();
131 // If commit requested but can_start is still false, do nothing.
133 StateMachine state(default_scheduler_settings);
134 state.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
135 state.SetNeedsRedraw(false);
136 state.SetVisible(true);
137 state.SetNeedsCommit();
139 EXPECT_FALSE(state.BeginFrameNeeded());
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();
148 // If commit requested, begin a main frame.
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();
159 EXPECT_TRUE(state.BeginFrameNeeded());
161 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
162 EXPECT_ACTION_UPDATE_STATE(
163 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
166 // Begin the frame, make sure needs_commit and commit_state update correctly.
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());
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();
195 EXPECT_TRUE(state.BeginFrameNeeded());
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);
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());
209 state.OnBeginImplFrameDeadline();
210 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
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);
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);
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);
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());
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();
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);
267 EXPECT_FALSE(state.RedrawPending());
268 EXPECT_FALSE(state.CommitPending());
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());
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());
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());
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());
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();
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();
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());
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);
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());
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);
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());
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);
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());
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());
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();
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);
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());
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);
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);
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());
458 // Now force redraw should be in waiting for activation
459 EXPECT_TRUE(state.ForcedRedrawState() ==
460 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION);
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);
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);
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);
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());
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);
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);
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);
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);
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);
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);
543 // Move to another frame. This should now draw.
544 EXPECT_TRUE(state.BeginFrameNeeded());
545 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
547 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
548 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
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);
558 // We just swapped, so we should proactively request another BeginImplFrame.
559 EXPECT_TRUE(state.BeginFrameNeeded());
562 TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) {
563 SchedulerSettings default_scheduler_settings;
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);
585 // Case 1: needs_commit=false
586 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
587 state.NextAction());
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();
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);
609 state.SetNeedsRedraw(true);
610 state.SetVisible(true);
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());
623 // Case 1: needs_commit=false.
624 EXPECT_EQ(state.NextAction(), expected_action)
625 << state.AsValue()->ToString();
627 // Case 2: needs_commit=true.
628 state.SetNeedsCommit();
629 EXPECT_EQ(state.NextAction(), expected_action)
630 << state.AsValue()->ToString();
634 TEST(SchedulerStateMachineTest, TestNoCommitStatesRedrawWhenInvisible) {
635 SchedulerSettings default_scheduler_settings;
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);
654 // Case 1: needs_commit=false.
655 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
656 state.NextAction());
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();
667 TEST(SchedulerStateMachineTest, TestCanRedraw_StopsDraw) {
668 SchedulerSettings default_scheduler_settings;
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());
685 state.SetCanDraw(false);
686 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
687 state.NextAction());
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();
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_ANIMATE);
707 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
708 EXPECT_ACTION_UPDATE_STATE(
709 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
710 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
711 state.NotifyBeginMainFrameStarted();
712 state.NotifyReadyToCommit();
713 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
714 state.OnBeginImplFrameDeadline();
715 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
716 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
717 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
720 TEST(SchedulerStateMachineTest, TestSetNeedsCommitIsNotLost) {
721 SchedulerSettings scheduler_settings;
722 StateMachine state(scheduler_settings);
723 state.SetCanStart();
724 state.UpdateState(state.NextAction());
725 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
726 state.SetNeedsCommit();
727 state.SetVisible(true);
728 state.SetCanDraw(true);
730 EXPECT_TRUE(state.BeginFrameNeeded());
732 // Begin the frame.
733 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
734 EXPECT_ACTION_UPDATE_STATE(
735 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
736 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
737 state.CommitState());
739 // Now, while the frame is in progress, set another commit.
740 state.SetNeedsCommit();
741 EXPECT_TRUE(state.NeedsCommit());
743 // Let the frame finish.
744 state.NotifyBeginMainFrameStarted();
745 state.NotifyReadyToCommit();
746 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
747 state.CommitState());
749 // Expect to commit regardless of BeginImplFrame state.
750 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
751 state.begin_impl_frame_state());
752 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
754 state.OnBeginImplFrameDeadlinePending();
755 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
756 state.begin_impl_frame_state());
757 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
759 state.OnBeginImplFrameDeadline();
760 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE,
761 state.begin_impl_frame_state());
762 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
764 state.OnBeginImplFrameIdle();
765 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
766 state.begin_impl_frame_state());
767 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
769 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
770 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
771 state.begin_impl_frame_state());
772 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
774 // Finish the commit, then make sure we start the next commit immediately
775 // and draw on the next BeginImplFrame.
776 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
777 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
778 EXPECT_ACTION_UPDATE_STATE(
779 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
780 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
782 state.OnBeginImplFrameDeadline();
784 EXPECT_TRUE(state.active_tree_needs_first_draw());
785 EXPECT_ACTION_UPDATE_STATE(
786 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
787 state.DidSwapBuffers();
788 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
789 state.DidSwapBuffersComplete();
790 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
793 TEST(SchedulerStateMachineTest, TestFullCycle) {
794 SchedulerSettings default_scheduler_settings;
795 StateMachine state(default_scheduler_settings);
796 state.SetCanStart();
797 state.UpdateState(state.NextAction());
798 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
799 state.SetVisible(true);
800 state.SetCanDraw(true);
802 // Start clean and set commit.
803 state.SetNeedsCommit();
805 // Begin the frame.
806 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
807 EXPECT_ACTION_UPDATE_STATE(
808 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
809 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
810 state.CommitState());
811 EXPECT_FALSE(state.NeedsCommit());
812 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
814 // Tell the scheduler the frame finished.
815 state.NotifyBeginMainFrameStarted();
816 state.NotifyReadyToCommit();
817 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
818 state.CommitState());
820 // Commit.
821 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
822 EXPECT_TRUE(state.active_tree_needs_first_draw());
823 EXPECT_TRUE(state.needs_redraw());
825 // Expect to do nothing until BeginImplFrame deadline
826 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
828 // At BeginImplFrame deadline, draw.
829 state.OnBeginImplFrameDeadline();
830 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
831 EXPECT_ACTION_UPDATE_STATE(
832 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
833 state.DidSwapBuffers();
834 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
835 state.DidSwapBuffersComplete();
837 // Should be synchronized, no draw needed, no action needed.
838 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
839 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
840 EXPECT_FALSE(state.needs_redraw());
843 TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) {
844 SchedulerSettings default_scheduler_settings;
845 StateMachine state(default_scheduler_settings);
846 state.SetCanStart();
847 state.UpdateState(state.NextAction());
848 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
849 state.SetVisible(true);
850 state.SetCanDraw(true);
852 // Start clean and set commit.
853 state.SetNeedsCommit();
855 // Begin the frame.
856 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
857 EXPECT_ACTION_UPDATE_STATE(
858 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
859 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
860 state.CommitState());
861 EXPECT_FALSE(state.NeedsCommit());
862 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
864 // Request another commit while the commit is in flight.
865 state.SetNeedsCommit();
866 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
868 // Tell the scheduler the frame finished.
869 state.NotifyBeginMainFrameStarted();
870 state.NotifyReadyToCommit();
871 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
872 state.CommitState());
874 // First commit.
875 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
876 EXPECT_TRUE(state.active_tree_needs_first_draw());
877 EXPECT_TRUE(state.needs_redraw());
879 // Expect to do nothing until BeginImplFrame deadline.
880 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
882 // At BeginImplFrame deadline, draw.
883 state.OnBeginImplFrameDeadline();
884 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
885 EXPECT_ACTION_UPDATE_STATE(
886 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
887 state.DidSwapBuffers();
888 state.DidDrawIfPossibleCompleted(DRAW_SUCCESS);
889 state.DidSwapBuffersComplete();
891 // Should be synchronized, no draw needed, no action needed.
892 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
893 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
894 EXPECT_FALSE(state.needs_redraw());
896 // Next BeginImplFrame should initiate second commit.
897 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
898 EXPECT_ACTION_UPDATE_STATE(
899 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
902 TEST(SchedulerStateMachineTest, TestRequestCommitInvisible) {
903 SchedulerSettings default_scheduler_settings;
904 StateMachine state(default_scheduler_settings);
905 state.SetCanStart();
906 state.UpdateState(state.NextAction());
907 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
908 state.SetNeedsCommit();
909 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
912 TEST(SchedulerStateMachineTest, TestGoesInvisibleBeforeFinishCommit) {
913 SchedulerSettings default_scheduler_settings;
914 StateMachine state(default_scheduler_settings);
915 state.SetCanStart();
916 state.UpdateState(state.NextAction());
917 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
918 state.SetVisible(true);
919 state.SetCanDraw(true);
921 // Start clean and set commit.
922 state.SetNeedsCommit();
924 // Begin the frame while visible.
925 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
926 EXPECT_ACTION_UPDATE_STATE(
927 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
928 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
929 state.CommitState());
930 EXPECT_FALSE(state.NeedsCommit());
931 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
933 // Become invisible and abort BeginMainFrame.
934 state.SetVisible(false);
935 state.BeginMainFrameAborted(false);
937 // We should now be back in the idle state as if we never started the frame.
938 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
939 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
941 // We shouldn't do anything on the BeginImplFrame deadline.
942 state.OnBeginImplFrameDeadline();
943 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
945 // Become visible again.
946 state.SetVisible(true);
948 // Although we have aborted on this frame and haven't cancelled the commit
949 // (i.e. need another), don't send another BeginMainFrame yet.
950 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
951 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
952 EXPECT_TRUE(state.NeedsCommit());
954 // Start a new frame.
955 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
956 EXPECT_ACTION_UPDATE_STATE(
957 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
959 // We should be starting the commit now.
960 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
961 state.CommitState());
962 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
965 TEST(SchedulerStateMachineTest, AbortBeginMainFrameAndCancelCommit) {
966 SchedulerSettings default_scheduler_settings;
967 StateMachine state(default_scheduler_settings);
968 state.SetCanStart();
969 state.UpdateState(state.NextAction());
970 state.DidCreateAndInitializeOutputSurface();
971 state.SetVisible(true);
972 state.SetCanDraw(true);
974 // Get into a begin frame / commit state.
975 state.SetNeedsCommit();
977 EXPECT_ACTION_UPDATE_STATE(
978 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
979 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
980 state.CommitState());
981 EXPECT_FALSE(state.NeedsCommit());
982 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
984 // Abort the commit, cancelling future commits.
985 state.BeginMainFrameAborted(true);
987 // Verify that another commit doesn't start on the same frame.
988 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
989 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
990 EXPECT_FALSE(state.NeedsCommit());
992 // Start a new frame; draw because this is the first frame since output
993 // surface init'd.
994 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
995 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
996 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
997 state.OnBeginImplFrameDeadline();
998 EXPECT_ACTION_UPDATE_STATE(
999 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1000 state.DidSwapBuffers();
1001 state.DidSwapBuffersComplete();
1003 // Verify another commit doesn't start on another frame either.
1004 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1005 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1006 EXPECT_FALSE(state.NeedsCommit());
1008 // Verify another commit can start if requested, though.
1009 state.SetNeedsCommit();
1010 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1011 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
1012 state.NextAction());
1015 TEST(SchedulerStateMachineTest,
1016 AbortBeginMainFrameAndCancelCommitWhenInvisible) {
1017 SchedulerSettings default_scheduler_settings;
1018 StateMachine state(default_scheduler_settings);
1019 state.SetCanStart();
1020 state.UpdateState(state.NextAction());
1021 state.DidCreateAndInitializeOutputSurface();
1022 state.SetVisible(true);
1023 state.SetCanDraw(true);
1025 // Get into a begin frame / commit state.
1026 state.SetNeedsCommit();
1028 EXPECT_ACTION_UPDATE_STATE(
1029 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1030 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
1031 state.CommitState());
1032 EXPECT_FALSE(state.NeedsCommit());
1033 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1035 // Become invisible and abort BeginMainFrame.
1036 state.SetVisible(false);
1037 state.BeginMainFrameAborted(true);
1039 // Verify that another commit doesn't start on the same frame.
1040 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1041 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1042 EXPECT_FALSE(state.NeedsCommit());
1044 // Become visible and start a new frame.
1045 state.SetVisible(true);
1046 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1047 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1048 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1050 // Draw because this is the first frame since output surface init'd.
1051 state.OnBeginImplFrameDeadline();
1052 EXPECT_ACTION_UPDATE_STATE(
1053 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1054 state.DidSwapBuffers();
1055 state.DidSwapBuffersComplete();
1057 // Verify another commit doesn't start on another frame either.
1058 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1059 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1060 EXPECT_FALSE(state.NeedsCommit());
1062 // Verify another commit can start if requested, though.
1063 state.SetNeedsCommit();
1064 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1065 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
1066 state.NextAction());
1069 TEST(SchedulerStateMachineTest,
1070 AbortBeginMainFrameAndRequestCommitWhenInvisible) {
1071 SchedulerSettings default_scheduler_settings;
1072 StateMachine state(default_scheduler_settings);
1073 state.SetCanStart();
1074 state.UpdateState(state.NextAction());
1075 state.DidCreateAndInitializeOutputSurface();
1076 state.SetVisible(true);
1077 state.SetCanDraw(true);
1079 // Get into a begin frame / commit state.
1080 state.SetNeedsCommit();
1082 EXPECT_ACTION_UPDATE_STATE(
1083 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1084 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
1085 state.CommitState());
1086 EXPECT_FALSE(state.NeedsCommit());
1087 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1089 // Become invisible and abort BeginMainFrame.
1090 state.SetVisible(false);
1091 state.BeginMainFrameAborted(true);
1093 // Verify that another commit doesn't start on the same frame.
1094 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1095 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1096 EXPECT_FALSE(state.NeedsCommit());
1098 // Asking for a commit while not visible won't make it happen.
1099 state.SetNeedsCommit();
1100 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1101 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1102 EXPECT_TRUE(state.NeedsCommit());
1104 // Become visible but nothing happens until the next frame.
1105 state.SetVisible(true);
1106 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1107 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1108 EXPECT_TRUE(state.NeedsCommit());
1110 // We should get that commit when we begin the next frame.
1111 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1112 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1113 EXPECT_ACTION_UPDATE_STATE(
1114 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1117 TEST(SchedulerStateMachineTest,
1118 AbortBeginMainFrameAndRequestCommitAndBeginImplFrameWhenInvisible) {
1119 SchedulerSettings default_scheduler_settings;
1120 StateMachine state(default_scheduler_settings);
1121 state.SetCanStart();
1122 state.UpdateState(state.NextAction());
1123 state.DidCreateAndInitializeOutputSurface();
1124 state.SetVisible(true);
1125 state.SetCanDraw(true);
1127 // Get into a begin frame / commit state.
1128 state.SetNeedsCommit();
1130 EXPECT_ACTION_UPDATE_STATE(
1131 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1132 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
1133 state.CommitState());
1134 EXPECT_FALSE(state.NeedsCommit());
1135 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1137 // Become invisible and abort BeginMainFrame.
1138 state.SetVisible(false);
1139 state.BeginMainFrameAborted(true);
1141 // Asking for a commit while not visible won't make it happen.
1142 state.SetNeedsCommit();
1143 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1144 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1145 EXPECT_TRUE(state.NeedsCommit());
1147 // Begin a frame when not visible, the scheduler animates but does not commit.
1148 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1149 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1150 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1151 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1152 EXPECT_TRUE(state.NeedsCommit());
1154 // Become visible and the requested commit happens immediately.
1155 state.SetVisible(true);
1156 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.CommitState());
1157 EXPECT_ACTION_UPDATE_STATE(
1158 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1161 TEST(SchedulerStateMachineTest, TestFirstContextCreation) {
1162 SchedulerSettings default_scheduler_settings;
1163 StateMachine state(default_scheduler_settings);
1164 state.SetCanStart();
1165 state.SetVisible(true);
1166 state.SetCanDraw(true);
1168 EXPECT_ACTION_UPDATE_STATE(
1169 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1170 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1171 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1173 // Check that the first init does not SetNeedsCommit.
1174 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1175 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1176 state.OnBeginImplFrameDeadline();
1177 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1179 // Check that a needs commit initiates a BeginMainFrame.
1180 state.SetNeedsCommit();
1181 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1182 EXPECT_ACTION_UPDATE_STATE(
1183 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1186 TEST(SchedulerStateMachineTest, TestContextLostWhenCompletelyIdle) {
1187 SchedulerSettings default_scheduler_settings;
1188 StateMachine state(default_scheduler_settings);
1189 state.SetCanStart();
1190 state.UpdateState(state.NextAction());
1191 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1193 state.SetVisible(true);
1194 state.SetCanDraw(true);
1196 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1197 state.NextAction());
1198 state.DidLoseOutputSurface();
1200 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1201 state.NextAction());
1202 state.UpdateState(state.NextAction());
1204 // Once context recreation begins, nothing should happen.
1205 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1207 // Recreate the context.
1208 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1210 // When the context is recreated, we should begin a commit.
1211 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1212 EXPECT_ACTION_UPDATE_STATE(
1213 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1216 TEST(SchedulerStateMachineTest,
1217 TestContextLostWhenIdleAndCommitRequestedWhileRecreating) {
1218 SchedulerSettings default_scheduler_settings;
1219 StateMachine state(default_scheduler_settings);
1220 state.SetCanStart();
1221 state.UpdateState(state.NextAction());
1222 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1223 state.SetVisible(true);
1224 state.SetCanDraw(true);
1226 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1227 state.NextAction());
1228 state.DidLoseOutputSurface();
1230 EXPECT_ACTION_UPDATE_STATE(
1231 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1232 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1234 // Once context recreation begins, nothing should happen.
1235 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1236 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1237 state.OnBeginImplFrameDeadline();
1238 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1240 // While context is recreating, commits shouldn't begin.
1241 state.SetNeedsCommit();
1242 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1243 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1244 state.OnBeginImplFrameDeadline();
1245 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1247 // Recreate the context
1248 state.DidCreateAndInitializeOutputSurface();
1249 EXPECT_FALSE(state.RedrawPending());
1251 // When the context is recreated, we should begin a commit
1252 EXPECT_ACTION_UPDATE_STATE(
1253 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1254 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1255 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT,
1256 state.CommitState());
1258 state.NotifyBeginMainFrameStarted();
1259 state.NotifyReadyToCommit();
1260 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1261 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1262 // Finishing the first commit after initializing an output surface should
1263 // automatically cause a redraw.
1264 EXPECT_TRUE(state.RedrawPending());
1266 // Once the context is recreated, whether we draw should be based on
1267 // SetCanDraw.
1268 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1269 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1270 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1271 state.OnBeginImplFrameDeadline();
1272 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
1273 state.NextAction());
1274 state.SetCanDraw(false);
1275 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT,
1276 state.NextAction());
1277 state.SetCanDraw(true);
1278 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE,
1279 state.NextAction());
1282 TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) {
1283 SchedulerSettings scheduler_settings;
1284 StateMachine state(scheduler_settings);
1285 state.SetCanStart();
1286 state.UpdateState(state.NextAction());
1287 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1288 state.SetVisible(true);
1289 state.SetCanDraw(true);
1291 // Get a commit in flight.
1292 state.SetNeedsCommit();
1294 // Set damage and expect a draw.
1295 state.SetNeedsRedraw(true);
1296 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1297 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1298 EXPECT_ACTION_UPDATE_STATE(
1299 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1300 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1301 state.OnBeginImplFrameDeadline();
1302 EXPECT_ACTION_UPDATE_STATE(
1303 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1304 state.DidSwapBuffers();
1305 state.DidSwapBuffersComplete();
1306 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1308 // Cause a lost context while the BeginMainFrame is in flight.
1309 state.DidLoseOutputSurface();
1311 // Ask for another draw. Expect nothing happens.
1312 state.SetNeedsRedraw(true);
1313 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1315 // Finish the frame, and commit.
1316 state.NotifyBeginMainFrameStarted();
1317 state.NotifyReadyToCommit();
1318 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1320 // We will abort the draw when the output surface is lost if we are
1321 // waiting for the first draw to unblock the main thread.
1322 EXPECT_TRUE(state.active_tree_needs_first_draw());
1323 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1325 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1326 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
1327 state.begin_impl_frame_state());
1328 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1329 state.NextAction());
1331 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1332 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
1333 state.begin_impl_frame_state());
1334 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1336 state.OnBeginImplFrameDeadlinePending();
1337 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
1338 state.begin_impl_frame_state());
1339 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1341 state.OnBeginImplFrameDeadline();
1342 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE,
1343 state.begin_impl_frame_state());
1344 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1347 TEST(SchedulerStateMachineTest,
1348 TestContextLostWhileCommitInProgressAndAnotherCommitRequested) {
1349 SchedulerSettings scheduler_settings;
1350 StateMachine state(scheduler_settings);
1351 state.SetCanStart();
1352 state.UpdateState(state.NextAction());
1353 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1354 state.SetVisible(true);
1355 state.SetCanDraw(true);
1357 // Get a commit in flight.
1358 state.SetNeedsCommit();
1359 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1361 // Set damage and expect a draw.
1362 state.SetNeedsRedraw(true);
1363 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1364 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1365 EXPECT_ACTION_UPDATE_STATE(
1366 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1367 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1368 state.OnBeginImplFrameDeadline();
1369 EXPECT_ACTION_UPDATE_STATE(
1370 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1371 state.DidSwapBuffers();
1372 state.DidSwapBuffersComplete();
1373 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1375 // Cause a lost context while the BeginMainFrame is in flight.
1376 state.DidLoseOutputSurface();
1378 // Ask for another draw and also set needs commit. Expect nothing happens.
1379 state.SetNeedsRedraw(true);
1380 state.SetNeedsCommit();
1381 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1383 // Finish the frame, and commit.
1384 state.NotifyBeginMainFrameStarted();
1385 state.NotifyReadyToCommit();
1386 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1387 EXPECT_TRUE(state.active_tree_needs_first_draw());
1389 // Because the output surface is missing, we expect the draw to abort.
1390 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1392 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1393 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE,
1394 state.begin_impl_frame_state());
1395 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1396 state.NextAction());
1398 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1399 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING,
1400 state.begin_impl_frame_state());
1401 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1403 state.OnBeginImplFrameDeadlinePending();
1404 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME,
1405 state.begin_impl_frame_state());
1406 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1408 state.OnBeginImplFrameDeadline();
1409 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE,
1410 state.begin_impl_frame_state());
1411 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1413 state.OnBeginImplFrameIdle();
1414 EXPECT_ACTION_UPDATE_STATE(
1415 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1417 // After we get a new output surface, the commit flow should start.
1418 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1419 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1420 EXPECT_ACTION_UPDATE_STATE(
1421 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1422 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1423 state.NotifyBeginMainFrameStarted();
1424 state.NotifyReadyToCommit();
1425 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1426 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1427 state.OnBeginImplFrameDeadline();
1428 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1429 EXPECT_ACTION_UPDATE_STATE(
1430 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1431 state.DidSwapBuffers();
1432 state.DidSwapBuffersComplete();
1433 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1436 TEST(SchedulerStateMachineTest, DontDrawBeforeCommitAfterLostOutputSurface) {
1437 SchedulerSettings default_scheduler_settings;
1438 StateMachine state(default_scheduler_settings);
1439 state.SetCanStart();
1440 state.UpdateState(state.NextAction());
1441 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1442 state.SetVisible(true);
1443 state.SetCanDraw(true);
1445 state.SetNeedsRedraw(true);
1447 // Cause a lost output surface, and restore it.
1448 state.DidLoseOutputSurface();
1449 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1450 state.NextAction());
1451 state.UpdateState(state.NextAction());
1452 state.DidCreateAndInitializeOutputSurface();
1454 EXPECT_FALSE(state.RedrawPending());
1455 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1456 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
1457 state.NextAction());
1460 TEST(SchedulerStateMachineTest,
1461 TestPendingActivationsShouldBeForcedAfterLostOutputSurface) {
1462 SchedulerSettings settings;
1463 settings.impl_side_painting = true;
1464 StateMachine state(settings);
1465 state.SetCanStart();
1466 state.UpdateState(state.NextAction());
1467 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1468 state.SetVisible(true);
1469 state.SetCanDraw(true);
1471 state.SetCommitState(
1472 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1474 // Cause a lost context.
1475 state.DidLoseOutputSurface();
1477 state.NotifyBeginMainFrameStarted();
1478 state.NotifyReadyToCommit();
1479 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1481 EXPECT_TRUE(state.PendingActivationsShouldBeForced());
1482 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1484 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1485 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1488 TEST(SchedulerStateMachineTest, TestNoBeginMainFrameWhenInvisible) {
1489 SchedulerSettings default_scheduler_settings;
1490 StateMachine state(default_scheduler_settings);
1491 state.SetCanStart();
1492 state.UpdateState(state.NextAction());
1493 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1494 state.SetVisible(false);
1495 state.SetNeedsCommit();
1496 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1499 TEST(SchedulerStateMachineTest, TestFinishCommitWhenCommitInProgress) {
1500 SchedulerSettings default_scheduler_settings;
1501 StateMachine state(default_scheduler_settings);
1502 state.SetCanStart();
1503 state.UpdateState(state.NextAction());
1504 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1505 state.SetVisible(false);
1506 state.SetCommitState(
1507 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1508 state.SetNeedsCommit();
1510 state.NotifyBeginMainFrameStarted();
1511 state.NotifyReadyToCommit();
1512 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
1513 state.UpdateState(state.NextAction());
1515 EXPECT_TRUE(state.active_tree_needs_first_draw());
1516 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
1519 TEST(SchedulerStateMachineTest, TestInitialActionsWhenContextLost) {
1520 SchedulerSettings default_scheduler_settings;
1521 StateMachine state(default_scheduler_settings);
1522 state.SetCanStart();
1523 state.UpdateState(state.NextAction());
1524 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1525 state.SetVisible(true);
1526 state.SetCanDraw(true);
1527 state.SetNeedsCommit();
1528 state.DidLoseOutputSurface();
1530 // When we are visible, we normally want to begin output surface creation
1531 // as soon as possible.
1532 EXPECT_ACTION_UPDATE_STATE(
1533 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1535 state.DidCreateAndInitializeOutputSurface();
1536 EXPECT_EQ(state.output_surface_state(),
1537 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT);
1539 // We should not send a BeginMainFrame when we are invisible, even if we've
1540 // lost the output surface and are trying to get the first commit, since the
1541 // main thread will just abort anyway.
1542 state.SetVisible(false);
1543 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction())
1544 << state.AsValue()->ToString();
1547 TEST(SchedulerStateMachineTest, ReportIfNotDrawing) {
1548 SchedulerSettings default_scheduler_settings;
1549 StateMachine state(default_scheduler_settings);
1550 state.SetCanStart();
1551 state.UpdateState(state.NextAction());
1552 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1554 state.SetCanDraw(true);
1555 state.SetVisible(true);
1556 EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
1558 state.SetCanDraw(false);
1559 state.SetVisible(true);
1560 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1562 state.SetCanDraw(true);
1563 state.SetVisible(false);
1564 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1566 state.SetCanDraw(false);
1567 state.SetVisible(false);
1568 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1570 state.SetCanDraw(true);
1571 state.SetVisible(true);
1572 EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
1575 TEST(SchedulerStateMachineTest, TestTriggerDeadlineEarlyAfterAbortedCommit) {
1576 SchedulerSettings settings;
1577 settings.impl_side_painting = true;
1578 StateMachine state(settings);
1579 state.SetCanStart();
1580 state.UpdateState(state.NextAction());
1581 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1582 state.SetVisible(true);
1583 state.SetCanDraw(true);
1585 // This test mirrors what happens during the first frame of a scroll gesture.
1586 // First we get the input event and a BeginFrame.
1587 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1589 // As a response the compositor requests a redraw and a commit to tell the
1590 // main thread about the new scroll offset.
1591 state.SetNeedsRedraw(true);
1592 state.SetNeedsCommit();
1594 // We should start the commit normally.
1595 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1596 EXPECT_ACTION_UPDATE_STATE(
1597 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1598 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1600 // Since only the scroll offset changed, the main thread will abort the
1601 // commit.
1602 state.BeginMainFrameAborted(true);
1604 // Since the commit was aborted, we should draw right away instead of waiting
1605 // for the deadline.
1606 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
1609 void FinishPreviousCommitAndDrawWithoutExitingDeadline(
1610 StateMachine* state_ptr) {
1611 // Gross, but allows us to use macros below.
1612 StateMachine& state = *state_ptr;
1614 state.NotifyBeginMainFrameStarted();
1615 state.NotifyReadyToCommit();
1616 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1617 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1618 state.NotifyReadyToActivate();
1619 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1620 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1622 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1623 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1624 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1626 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
1627 state.OnBeginImplFrameDeadline();
1628 EXPECT_ACTION_UPDATE_STATE(
1629 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1630 state.DidSwapBuffers();
1633 TEST(SchedulerStateMachineTest, TestImplLatencyTakesPriority) {
1634 SchedulerSettings settings;
1635 settings.impl_side_painting = true;
1636 StateMachine state(settings);
1637 state.SetCanStart();
1638 state.UpdateState(state.NextAction());
1639 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1640 state.SetVisible(true);
1641 state.SetCanDraw(true);
1643 // This test ensures that impl-draws are prioritized over main thread updates
1644 // in prefer impl latency mode.
1645 state.SetNeedsRedraw(true);
1646 state.SetNeedsCommit();
1647 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1648 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1649 EXPECT_ACTION_UPDATE_STATE(
1650 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1651 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1653 // Verify the deadline is not triggered early until we enter
1654 // prefer impl latency mode.
1655 EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
1656 state.SetImplLatencyTakesPriority(true);
1657 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
1659 // Trigger the deadline.
1660 state.OnBeginImplFrameDeadline();
1661 EXPECT_ACTION_UPDATE_STATE(
1662 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1663 state.DidSwapBuffers();
1664 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1665 state.DidSwapBuffersComplete();
1667 // Request a new commit and finish the previous one.
1668 state.SetNeedsCommit();
1669 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state);
1670 EXPECT_ACTION_UPDATE_STATE(
1671 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1672 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1673 state.DidSwapBuffersComplete();
1674 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1676 // Finish the previous commit and draw it.
1677 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state);
1678 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1680 // Verify we do not send another BeginMainFrame if was are swap throttled
1681 // and did not just swap.
1682 state.SetNeedsCommit();
1683 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1684 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1685 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1686 EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
1687 state.OnBeginImplFrameDeadline();
1688 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1691 TEST(SchedulerStateMachineTest, TestTriggerDeadlineEarlyOnLostOutputSurface) {
1692 SchedulerSettings default_scheduler_settings;
1693 StateMachine state(default_scheduler_settings);
1694 state.SetCanStart();
1695 state.UpdateState(state.NextAction());
1696 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1697 state.SetVisible(true);
1698 state.SetCanDraw(true);
1700 state.SetNeedsCommit();
1702 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1703 EXPECT_ACTION_UPDATE_STATE(
1704 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1705 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1706 EXPECT_FALSE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
1708 state.DidLoseOutputSurface();
1709 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1710 // The deadline should be triggered immediately when output surface is lost.
1711 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
1714 TEST(SchedulerStateMachineTest, TestSetNeedsAnimate) {
1715 SchedulerSettings settings;
1716 settings.impl_side_painting = true;
1717 StateMachine state(settings);
1718 state.SetCanStart();
1719 state.UpdateState(state.NextAction());
1720 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1721 state.SetVisible(true);
1722 state.SetCanDraw(true);
1724 // Test requesting an animation that, when run, causes us to draw.
1725 state.SetNeedsAnimate();
1726 EXPECT_TRUE(state.BeginFrameNeeded());
1727 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1729 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1730 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1732 state.OnBeginImplFrameDeadlinePending();
1733 state.OnBeginImplFrameDeadline();
1734 EXPECT_ACTION_UPDATE_STATE(
1735 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1738 TEST(SchedulerStateMachineTest, TestAnimateBeforeCommit) {
1739 SchedulerSettings settings;
1740 settings.impl_side_painting = true;
1741 StateMachine state(settings);
1742 state.SetCanStart();
1743 state.UpdateState(state.NextAction());
1744 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1745 state.SetVisible(true);
1746 state.SetCanDraw(true);
1748 // Check that animations are updated before we start a commit.
1749 state.SetNeedsAnimate();
1750 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1751 state.SetNeedsCommit();
1752 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1753 EXPECT_TRUE(state.BeginFrameNeeded());
1755 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1756 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1757 EXPECT_ACTION_UPDATE_STATE(
1758 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1760 state.OnBeginImplFrameDeadlinePending();
1761 state.OnBeginImplFrameDeadline();
1762 EXPECT_ACTION_UPDATE_STATE(
1763 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1766 TEST(SchedulerStateMachineTest, TestAnimateAfterCommitBeforeDraw) {
1767 SchedulerSettings settings;
1768 settings.impl_side_painting = true;
1769 StateMachine state(settings);
1770 state.SetCanStart();
1771 state.UpdateState(state.NextAction());
1772 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1773 state.SetVisible(true);
1774 state.SetCanDraw(true);
1776 // Check that animations are updated before we start a commit.
1777 state.SetNeedsAnimate();
1778 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1779 state.SetNeedsCommit();
1780 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1781 EXPECT_TRUE(state.BeginFrameNeeded());
1783 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1784 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1785 EXPECT_ACTION_UPDATE_STATE(
1786 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1788 state.NotifyBeginMainFrameStarted();
1789 state.NotifyReadyToCommit();
1790 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1792 state.OnBeginImplFrameDeadlinePending();
1793 state.OnBeginImplFrameDeadline();
1794 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1795 EXPECT_ACTION_UPDATE_STATE(
1796 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1799 TEST(SchedulerStateMachineTest, TestSetNeedsAnimateAfterAnimate) {
1800 SchedulerSettings settings;
1801 settings.impl_side_painting = true;
1802 StateMachine state(settings);
1803 state.SetCanStart();
1804 state.UpdateState(state.NextAction());
1805 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1806 state.SetVisible(true);
1807 state.SetCanDraw(true);
1809 // Test requesting an animation after we have already animated during this
1810 // frame.
1811 state.SetNeedsRedraw(true);
1812 EXPECT_TRUE(state.BeginFrameNeeded());
1813 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1815 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1816 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1818 state.SetNeedsAnimate();
1819 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1821 state.OnBeginImplFrameDeadline();
1822 EXPECT_ACTION_UPDATE_STATE(
1823 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1826 } // namespace
1827 } // namespace cc