Change DtmfSenderHandler to handle events on the signaling thread.
[chromium-blink-merge.git] / cc / scheduler / scheduler_state_machine_unittest.cc
blobe3530c877f4cb68bbf793217225dcc1fe3b4bf24
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_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);
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);
728 EXPECT_TRUE(state.BeginFrameNeeded());
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());
737 // Now, while the frame is in progress, set another commit.
738 state.SetNeedsCommit();
739 EXPECT_TRUE(state.NeedsCommit());
741 // Let the frame finish.
742 state.NotifyBeginMainFrameStarted();
743 state.NotifyReadyToCommit();
744 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
745 state.CommitState());
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());
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());
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());
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());
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());
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);
780 state.OnBeginImplFrameDeadline();
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);
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);
800 // Start clean and set commit.
801 state.SetNeedsCommit();
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);
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());
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());
823 // Expect to do nothing until BeginImplFrame deadline
824 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
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();
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());
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);
850 // Start clean and set commit.
851 state.SetNeedsCommit();
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);
862 // Request another commit while the commit is in flight.
863 state.SetNeedsCommit();
864 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
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());
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());
877 // Expect to do nothing until BeginImplFrame deadline.
878 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
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();
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());
894 // Next BeginImplFrame should initiate second commit.
895 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
896 EXPECT_ACTION_UPDATE_STATE(
897 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
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);
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);
919 // Start clean and set commit.
920 state.SetNeedsCommit();
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);
931 // Become invisible and abort BeginMainFrame.
932 state.SetVisible(false);
933 state.BeginMainFrameAborted(false);
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);
939 // We shouldn't do anything on the BeginImplFrame deadline.
940 state.OnBeginImplFrameDeadline();
941 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
943 // Become visible again.
944 state.SetVisible(true);
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());
952 // Start a new frame.
953 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
954 EXPECT_ACTION_UPDATE_STATE(
955 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
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);
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);
972 // Get into a begin frame / commit state.
973 state.SetNeedsCommit();
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());
982 // Abort the commit, cancelling future commits.
983 state.BeginMainFrameAborted(true);
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());
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();
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());
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());
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);
1023 // Get into a begin frame / commit state.
1024 state.SetNeedsCommit();
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());
1033 // Become invisible and abort BeginMainFrame.
1034 state.SetVisible(false);
1035 state.BeginMainFrameAborted(true);
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());
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);
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();
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());
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());
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);
1077 // Get into a begin frame / commit state.
1078 state.SetNeedsCommit();
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());
1087 // Become invisible and abort BeginMainFrame.
1088 state.SetVisible(false);
1089 state.BeginMainFrameAborted(true);
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());
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());
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());
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);
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);
1125 // Get into a begin frame / commit state.
1126 state.SetNeedsCommit();
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());
1135 // Become invisible and abort BeginMainFrame.
1136 state.SetVisible(false);
1137 state.BeginMainFrameAborted(true);
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());
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());
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);
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);
1166 EXPECT_ACTION_UPDATE_STATE(
1167 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1168 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1169 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
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);
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);
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();
1191 state.SetVisible(true);
1192 state.SetCanDraw(true);
1194 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1195 state.NextAction());
1196 state.DidLoseOutputSurface();
1198 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1199 state.NextAction());
1200 state.UpdateState(state.NextAction());
1202 // Once context recreation begins, nothing should happen.
1203 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1205 // Recreate the context.
1206 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
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);
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);
1224 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
1225 state.NextAction());
1226 state.DidLoseOutputSurface();
1228 EXPECT_ACTION_UPDATE_STATE(
1229 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
1230 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
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);
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);
1245 // Recreate the context
1246 state.DidCreateAndInitializeOutputSurface();
1247 EXPECT_FALSE(state.RedrawPending());
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());
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());
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());
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);
1289 // Get a commit in flight.
1290 state.SetNeedsCommit();
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);
1306 // Cause a lost context while the BeginMainFrame is in flight.
1307 state.DidLoseOutputSurface();
1309 // Ask for another draw. Expect nothing happens.
1310 state.SetNeedsRedraw(true);
1311 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.NextAction());
1313 // Finish the frame, and commit.
1314 state.NotifyBeginMainFrameStarted();
1315 state.NotifyReadyToCommit();
1316 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
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);
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());
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());
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());
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());
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);
1355 // Get a commit in flight.
1356 state.SetNeedsCommit();
1357 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
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);
1373 // Cause a lost context while the BeginMainFrame is in flight.
1374 state.DidLoseOutputSurface();
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);
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());
1387 // Because the output surface is missing, we expect the draw to abort.
1388 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
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());
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());
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());
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());
1411 state.OnBeginImplFrameIdle();
1412 EXPECT_ACTION_UPDATE_STATE(
1413 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION);
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);
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);
1443 state.SetNeedsRedraw(true);
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();
1452 EXPECT_FALSE(state.RedrawPending());
1453 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1454 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME,
1455 state.NextAction());
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);
1469 state.SetCommitState(
1470 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT);
1472 // Cause a lost context.
1473 state.DidLoseOutputSurface();
1475 state.NotifyBeginMainFrameStarted();
1476 state.NotifyReadyToCommit();
1477 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
1479 EXPECT_TRUE(state.PendingActivationsShouldBeForced());
1480 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
1482 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1483 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
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());
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();
1508 state.NotifyBeginMainFrameStarted();
1509 state.NotifyReadyToCommit();
1510 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.NextAction());
1511 state.UpdateState(state.NextAction());
1513 EXPECT_TRUE(state.active_tree_needs_first_draw());
1514 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT);
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();
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);
1533 state.DidCreateAndInitializeOutputSurface();
1534 EXPECT_EQ(state.output_surface_state(),
1535 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT);
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();
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();
1552 state.SetCanDraw(true);
1553 state.SetVisible(true);
1554 EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
1556 state.SetCanDraw(false);
1557 state.SetVisible(true);
1558 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1560 state.SetCanDraw(true);
1561 state.SetVisible(false);
1562 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1564 state.SetCanDraw(false);
1565 state.SetVisible(false);
1566 EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
1568 state.SetCanDraw(true);
1569 state.SetVisible(true);
1570 EXPECT_FALSE(state.PendingDrawsShouldBeAborted());
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);
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());
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();
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);
1598 // Since only the scroll offset changed, the main thread will abort the
1599 // commit.
1600 state.BeginMainFrameAborted(true);
1602 // Since the commit was aborted, we should draw right away instead of waiting
1603 // for the deadline.
1604 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
1607 void FinishPreviousCommitAndDrawWithoutExitingDeadline(
1608 StateMachine* state_ptr) {
1609 // Gross, but allows us to use macros below.
1610 StateMachine& state = *state_ptr;
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);
1620 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1621 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1622 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1624 EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineEarly());
1625 state.OnBeginImplFrameDeadline();
1626 EXPECT_ACTION_UPDATE_STATE(
1627 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1628 state.DidSwapBuffers();
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);
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);
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());
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();
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);
1674 // Finish the previous commit and draw it.
1675 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state);
1676 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
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);
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);
1698 state.SetNeedsCommit();
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());
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());
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);
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);
1727 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1728 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1730 state.OnBeginImplFrameDeadlinePending();
1731 state.OnBeginImplFrameDeadline();
1732 EXPECT_ACTION_UPDATE_STATE(
1733 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
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);
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());
1753 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1754 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1755 EXPECT_ACTION_UPDATE_STATE(
1756 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1758 state.OnBeginImplFrameDeadlinePending();
1759 state.OnBeginImplFrameDeadline();
1760 EXPECT_ACTION_UPDATE_STATE(
1761 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
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);
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());
1781 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1782 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1783 EXPECT_ACTION_UPDATE_STATE(
1784 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
1786 state.NotifyBeginMainFrameStarted();
1787 state.NotifyReadyToCommit();
1788 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
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);
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);
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);
1813 state.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1814 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE);
1816 state.SetNeedsAnimate();
1817 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
1819 state.OnBeginImplFrameDeadline();
1820 EXPECT_ACTION_UPDATE_STATE(
1821 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE);
1824 } // namespace
1825 } // namespace cc