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 "cc/scheduler/scheduler.h"
8 #include "cc/test/begin_frame_args_test.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 #define EXPECT_ACTION_UPDATE_STATE(action) \
12 EXPECT_EQ(action, state.NextAction()) << *state.AsValue(); \
13 if (action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE || \
14 action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED) { \
15 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE, \
16 state.begin_impl_frame_state()) \
17 << *state.AsValue(); \
19 state.UpdateState(action); \
20 if (action == SchedulerStateMachine::ACTION_NONE) { \
21 if (state.begin_impl_frame_state() == \
22 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING) \
23 state.OnBeginImplFrameDeadlinePending(); \
24 if (state.begin_impl_frame_state() == \
25 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) \
26 state.OnBeginImplFrameIdle(); \
33 const SchedulerStateMachine::BeginImplFrameState all_begin_impl_frame_states
[] =
34 {SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
35 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
36 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
37 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
, };
39 const SchedulerStateMachine::CommitState all_commit_states
[] = {
40 SchedulerStateMachine::COMMIT_STATE_IDLE
,
41 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
42 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_STARTED
,
43 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
44 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_ACTIVATION
,
45 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
};
47 // Exposes the protected state fields of the SchedulerStateMachine for testing
48 class StateMachine
: public SchedulerStateMachine
{
50 explicit StateMachine(const SchedulerSettings
& scheduler_settings
)
51 : SchedulerStateMachine(scheduler_settings
) {}
53 void CreateAndInitializeOutputSurfaceWithActivatedCommit() {
54 DidCreateAndInitializeOutputSurface();
55 output_surface_state_
= OUTPUT_SURFACE_ACTIVE
;
58 void SetCommitState(CommitState cs
) { commit_state_
= cs
; }
59 CommitState
CommitState() const { return commit_state_
; }
61 ForcedRedrawOnTimeoutState
ForcedRedrawState() const {
62 return forced_redraw_state_
;
65 void SetBeginImplFrameState(BeginImplFrameState bifs
) {
66 begin_impl_frame_state_
= bifs
;
69 BeginImplFrameState
begin_impl_frame_state() const {
70 return begin_impl_frame_state_
;
73 OutputSurfaceState
output_surface_state() const {
74 return output_surface_state_
;
77 bool NeedsCommit() const { return needs_commit_
; }
79 void SetNeedsRedraw(bool b
) { needs_redraw_
= b
; }
81 void SetNeedsForcedRedrawForTimeout(bool b
) {
82 forced_redraw_state_
= FORCED_REDRAW_STATE_WAITING_FOR_COMMIT
;
83 active_tree_needs_first_draw_
= true;
85 bool NeedsForcedRedrawForTimeout() const {
86 return forced_redraw_state_
!= FORCED_REDRAW_STATE_IDLE
;
89 void SetActiveTreeNeedsFirstDraw(bool needs_first_draw
) {
90 active_tree_needs_first_draw_
= needs_first_draw
;
93 bool CanDraw() const { return can_draw_
; }
94 bool Visible() const { return visible_
; }
96 bool PendingActivationsShouldBeForced() const {
97 return SchedulerStateMachine::PendingActivationsShouldBeForced();
100 void SetHasPendingTree(bool has_pending_tree
) {
101 has_pending_tree_
= has_pending_tree
;
105 TEST(SchedulerStateMachineTest
, TestNextActionBeginsMainFrameIfNeeded
) {
106 SchedulerSettings default_scheduler_settings
;
108 // If no commit needed, do nothing.
110 StateMachine
state(default_scheduler_settings
);
112 EXPECT_ACTION_UPDATE_STATE(
113 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
)
114 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
115 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
116 state
.SetNeedsRedraw(false);
117 state
.SetVisible(true);
119 EXPECT_FALSE(state
.BeginFrameNeeded());
121 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
122 EXPECT_FALSE(state
.BeginFrameNeeded());
123 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
125 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
126 state
.OnBeginImplFrameDeadline();
129 // If commit requested but can_start is still false, do nothing.
131 StateMachine
state(default_scheduler_settings
);
132 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
133 state
.SetNeedsRedraw(false);
134 state
.SetVisible(true);
135 state
.SetNeedsCommit();
137 EXPECT_FALSE(state
.BeginFrameNeeded());
139 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
140 EXPECT_FALSE(state
.BeginFrameNeeded());
141 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
142 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
143 state
.OnBeginImplFrameDeadline();
146 // If commit requested, begin a main frame.
148 StateMachine
state(default_scheduler_settings
);
149 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
151 state
.UpdateState(state
.NextAction());
152 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
153 state
.SetNeedsRedraw(false);
154 state
.SetVisible(true);
155 state
.SetNeedsCommit();
157 EXPECT_TRUE(state
.BeginFrameNeeded());
159 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
160 EXPECT_ACTION_UPDATE_STATE(
161 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
164 // Begin the frame, make sure needs_commit and commit_state update correctly.
166 StateMachine
state(default_scheduler_settings
);
168 state
.UpdateState(state
.NextAction());
169 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
170 state
.SetVisible(true);
171 state
.UpdateState(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
172 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
173 state
.CommitState());
174 EXPECT_FALSE(state
.NeedsCommit());
178 // Explicitly test main_frame_before_draw_enabled = false
179 TEST(SchedulerStateMachineTest
, MainFrameBeforeDrawDisabled
) {
180 SchedulerSettings scheduler_settings
;
181 scheduler_settings
.impl_side_painting
= true;
182 scheduler_settings
.main_frame_before_draw_enabled
= false;
183 StateMachine
state(scheduler_settings
);
184 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
186 state
.UpdateState(state
.NextAction());
187 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
188 state
.SetNeedsRedraw(false);
189 state
.SetVisible(true);
190 state
.SetCanDraw(true);
191 state
.SetNeedsCommit();
193 EXPECT_TRUE(state
.BeginFrameNeeded());
195 // Commit to the pending tree.
196 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
197 EXPECT_ACTION_UPDATE_STATE(
198 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
199 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
200 state
.NotifyBeginMainFrameStarted();
201 state
.NotifyReadyToCommit();
202 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
203 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
204 EXPECT_EQ(state
.CommitState(),
205 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
);
207 state
.OnBeginImplFrameDeadline();
208 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
209 EXPECT_EQ(state
.CommitState(),
210 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
);
212 // Verify that the next commit doesn't start until the previous
213 // commit has been drawn.
214 state
.SetNeedsCommit();
215 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
216 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
218 // Make sure that a draw of the active tree doesn't spuriously advance
219 // the commit state and unblock the next commit.
220 state
.SetNeedsRedraw(true);
221 state
.OnBeginImplFrameDeadline();
222 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
223 EXPECT_ACTION_UPDATE_STATE(
224 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
225 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
226 EXPECT_EQ(state
.CommitState(),
227 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
);
228 EXPECT_TRUE(state
.has_pending_tree());
230 // Verify NotifyReadyToActivate unblocks activation, draw, and
231 // commit in that order.
232 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
234 state
.NotifyReadyToActivate();
235 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
236 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
237 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
238 EXPECT_EQ(state
.CommitState(),
239 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
);
241 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
242 state
.OnBeginImplFrameDeadline();
243 EXPECT_ACTION_UPDATE_STATE(
244 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
245 state
.DidSwapBuffers();
246 state
.DidSwapBuffersComplete();
247 EXPECT_EQ(state
.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE
);
248 EXPECT_ACTION_UPDATE_STATE(
249 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
250 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
251 EXPECT_EQ(state
.CommitState(),
252 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
254 state
.NotifyBeginMainFrameStarted();
255 state
.NotifyReadyToCommit();
256 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
257 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
258 EXPECT_EQ(state
.CommitState(),
259 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
);
262 // Explicitly test main_frame_before_activation_enabled = true
263 TEST(SchedulerStateMachineTest
, MainFrameBeforeActivationEnabled
) {
264 SchedulerSettings scheduler_settings
;
265 scheduler_settings
.impl_side_painting
= true;
266 scheduler_settings
.main_frame_before_activation_enabled
= true;
267 StateMachine
state(scheduler_settings
);
268 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
270 state
.UpdateState(state
.NextAction());
271 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
272 state
.SetNeedsRedraw(false);
273 state
.SetVisible(true);
274 state
.SetCanDraw(true);
275 state
.SetNeedsCommit();
277 EXPECT_TRUE(state
.BeginFrameNeeded());
279 // Commit to the pending tree.
280 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
281 EXPECT_ACTION_UPDATE_STATE(
282 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
283 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
285 state
.NotifyBeginMainFrameStarted();
286 state
.NotifyReadyToCommit();
287 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
288 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
289 EXPECT_EQ(state
.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE
);
291 state
.OnBeginImplFrameDeadline();
292 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
294 // Verify that the next commit starts while there is still a pending tree.
295 state
.SetNeedsCommit();
296 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
297 EXPECT_ACTION_UPDATE_STATE(
298 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
299 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
301 // Verify the pending commit doesn't overwrite the pending
302 // tree until the pending tree has been activated.
303 state
.NotifyBeginMainFrameStarted();
304 state
.NotifyReadyToCommit();
305 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
307 // Verify NotifyReadyToActivate unblocks activation, draw, and
308 // commit in that order.
309 state
.NotifyReadyToActivate();
310 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
311 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
313 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
314 state
.OnBeginImplFrameDeadline();
315 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
316 EXPECT_ACTION_UPDATE_STATE(
317 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
318 state
.DidSwapBuffers();
319 state
.DidSwapBuffersComplete();
320 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
321 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
322 EXPECT_EQ(state
.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE
);
325 TEST(SchedulerStateMachineTest
,
326 TestFailedDrawForAnimationCheckerboardSetsNeedsCommitAndDoesNotDrawAgain
) {
327 SchedulerSettings default_scheduler_settings
;
328 StateMachine
state(default_scheduler_settings
);
330 state
.UpdateState(state
.NextAction());
331 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
332 state
.SetVisible(true);
333 state
.SetCanDraw(true);
334 state
.SetNeedsRedraw(true);
335 EXPECT_TRUE(state
.RedrawPending());
336 EXPECT_TRUE(state
.BeginFrameNeeded());
337 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
338 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
339 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
340 state
.OnBeginImplFrameDeadline();
342 // We're drawing now.
343 EXPECT_ACTION_UPDATE_STATE(
344 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
345 state
.DidSwapBuffers();
346 state
.DidSwapBuffersComplete();
347 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
349 EXPECT_FALSE(state
.RedrawPending());
350 EXPECT_FALSE(state
.CommitPending());
352 // Failing the draw makes us require a commit.
353 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
354 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
355 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
356 EXPECT_ACTION_UPDATE_STATE(
357 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
358 EXPECT_TRUE(state
.RedrawPending());
359 EXPECT_TRUE(state
.CommitPending());
362 TEST(SchedulerStateMachineTest
, TestFailedDrawForMissingHighResNeedsCommit
) {
363 SchedulerSettings default_scheduler_settings
;
364 StateMachine
state(default_scheduler_settings
);
366 state
.UpdateState(state
.NextAction());
367 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
368 state
.SetVisible(true);
369 state
.SetCanDraw(true);
370 state
.SetNeedsRedraw(true);
371 EXPECT_TRUE(state
.RedrawPending());
372 EXPECT_TRUE(state
.BeginFrameNeeded());
374 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
375 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
376 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
377 state
.OnBeginImplFrameDeadline();
378 EXPECT_ACTION_UPDATE_STATE(
379 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
380 state
.DidSwapBuffers();
381 state
.DidSwapBuffersComplete();
382 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
383 EXPECT_FALSE(state
.RedrawPending());
384 EXPECT_FALSE(state
.CommitPending());
386 // Missing high res content requires a commit (but not a redraw)
387 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
);
388 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
389 EXPECT_ACTION_UPDATE_STATE(
390 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
391 EXPECT_FALSE(state
.RedrawPending());
392 EXPECT_TRUE(state
.CommitPending());
395 TEST(SchedulerStateMachineTest
,
396 TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw
) {
397 SchedulerSettings default_scheduler_settings
;
398 StateMachine
state(default_scheduler_settings
);
400 state
.UpdateState(state
.NextAction());
401 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
403 state
.SetVisible(true);
404 state
.SetCanDraw(true);
405 state
.SetNeedsRedraw(true);
406 EXPECT_TRUE(state
.RedrawPending());
407 EXPECT_TRUE(state
.BeginFrameNeeded());
408 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
409 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
410 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
411 state
.OnBeginImplFrameDeadline();
413 // We're drawing now.
414 EXPECT_ACTION_UPDATE_STATE(
415 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
416 state
.DidSwapBuffers();
417 state
.DidSwapBuffersComplete();
418 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
419 EXPECT_FALSE(state
.RedrawPending());
420 EXPECT_FALSE(state
.CommitPending());
422 // While still in the same BeginMainFrame callback on the main thread,
423 // set needs redraw again. This should not redraw.
424 state
.SetNeedsRedraw(true);
425 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
427 // Failing the draw for animation checkerboards makes us require a commit.
428 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
429 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
430 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
431 EXPECT_ACTION_UPDATE_STATE(
432 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
433 EXPECT_TRUE(state
.RedrawPending());
436 void TestFailedDrawsEventuallyForceDrawAfterNextCommit(
437 bool main_frame_before_draw_enabled
) {
438 SchedulerSettings scheduler_settings
;
439 scheduler_settings
.main_frame_before_draw_enabled
=
440 main_frame_before_draw_enabled
;
441 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced_
= 1;
442 StateMachine
state(scheduler_settings
);
444 state
.UpdateState(state
.NextAction());
445 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
446 state
.SetVisible(true);
447 state
.SetCanDraw(true);
450 state
.SetNeedsCommit();
451 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
452 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
453 EXPECT_ACTION_UPDATE_STATE(
454 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
455 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
456 EXPECT_TRUE(state
.CommitPending());
458 // Then initiate a draw.
459 state
.SetNeedsRedraw(true);
460 state
.OnBeginImplFrameDeadline();
461 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
462 EXPECT_ACTION_UPDATE_STATE(
463 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
466 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
467 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
468 EXPECT_TRUE(state
.BeginFrameNeeded());
469 EXPECT_TRUE(state
.RedrawPending());
470 // But the commit is ongoing.
471 EXPECT_TRUE(state
.CommitPending());
473 // Finish the commit. Note, we should not yet be forcing a draw, but should
474 // continue the commit as usual.
475 state
.NotifyBeginMainFrameStarted();
476 state
.NotifyReadyToCommit();
477 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
478 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
479 EXPECT_TRUE(state
.RedrawPending());
481 // The redraw should be forced at the end of the next BeginImplFrame.
482 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
483 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
484 if (main_frame_before_draw_enabled
) {
485 EXPECT_ACTION_UPDATE_STATE(
486 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
488 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
489 state
.OnBeginImplFrameDeadline();
490 EXPECT_ACTION_UPDATE_STATE(
491 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED
);
492 state
.DidSwapBuffers();
493 state
.DidSwapBuffersComplete();
496 TEST(SchedulerStateMachineTest
,
497 TestFailedDrawsEventuallyForceDrawAfterNextCommit
) {
498 bool main_frame_before_draw_enabled
= false;
499 TestFailedDrawsEventuallyForceDrawAfterNextCommit(
500 main_frame_before_draw_enabled
);
503 TEST(SchedulerStateMachineTest
,
504 TestFailedDrawsEventuallyForceDrawAfterNextCommit_CommitBeforeDraw
) {
505 bool main_frame_before_draw_enabled
= true;
506 TestFailedDrawsEventuallyForceDrawAfterNextCommit(
507 main_frame_before_draw_enabled
);
510 TEST(SchedulerStateMachineTest
, TestFailedDrawsDoNotRestartForcedDraw
) {
511 SchedulerSettings scheduler_settings
;
513 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced_
=
515 scheduler_settings
.impl_side_painting
= true;
516 StateMachine
state(scheduler_settings
);
518 state
.UpdateState(state
.NextAction());
519 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
520 state
.SetVisible(true);
521 state
.SetCanDraw(true);
524 state
.SetNeedsCommit();
525 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
526 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
527 EXPECT_ACTION_UPDATE_STATE(
528 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
529 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
530 EXPECT_TRUE(state
.CommitPending());
532 // Then initiate a draw.
533 state
.SetNeedsRedraw(true);
534 state
.OnBeginImplFrameDeadline();
535 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
536 EXPECT_ACTION_UPDATE_STATE(
537 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
539 // Fail the draw enough times to force a redraw,
540 // then once more for good measure.
541 for (int i
= 0; i
< draw_limit
+ 1; ++i
)
542 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
543 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
544 EXPECT_TRUE(state
.BeginFrameNeeded());
545 EXPECT_TRUE(state
.RedrawPending());
546 // But the commit is ongoing.
547 EXPECT_TRUE(state
.CommitPending());
548 EXPECT_TRUE(state
.ForcedRedrawState() ==
549 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT
);
551 state
.NotifyBeginMainFrameStarted();
552 state
.NotifyReadyToCommit();
553 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
554 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
555 EXPECT_TRUE(state
.RedrawPending());
556 EXPECT_FALSE(state
.CommitPending());
558 // Now force redraw should be in waiting for activation
559 EXPECT_TRUE(state
.ForcedRedrawState() ==
560 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
562 // After failing additional draws, we should still be in a forced
563 // redraw, but not back in WAITING_FOR_COMMIT.
564 for (int i
= 0; i
< draw_limit
+ 1; ++i
)
565 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
566 EXPECT_TRUE(state
.RedrawPending());
567 EXPECT_TRUE(state
.ForcedRedrawState() ==
568 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
571 TEST(SchedulerStateMachineTest
, TestFailedDrawIsRetriedInNextBeginImplFrame
) {
572 SchedulerSettings default_scheduler_settings
;
573 StateMachine
state(default_scheduler_settings
);
575 state
.UpdateState(state
.NextAction());
576 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
577 state
.SetVisible(true);
578 state
.SetCanDraw(true);
581 state
.SetNeedsRedraw(true);
582 EXPECT_TRUE(state
.BeginFrameNeeded());
583 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
584 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
585 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
586 state
.OnBeginImplFrameDeadline();
587 EXPECT_TRUE(state
.RedrawPending());
588 EXPECT_ACTION_UPDATE_STATE(
589 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
591 // Failing the draw for animation checkerboards makes us require a commit.
592 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
593 EXPECT_ACTION_UPDATE_STATE(
594 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
595 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
596 EXPECT_TRUE(state
.RedrawPending());
598 // We should not be trying to draw again now, but we have a commit pending.
599 EXPECT_TRUE(state
.BeginFrameNeeded());
600 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
601 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
602 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
604 // We should try to draw again at the end of the next BeginImplFrame on
606 state
.OnBeginImplFrameDeadline();
607 EXPECT_ACTION_UPDATE_STATE(
608 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
609 state
.DidSwapBuffers();
610 state
.DidSwapBuffersComplete();
611 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
614 TEST(SchedulerStateMachineTest
, TestDoestDrawTwiceInSameFrame
) {
615 SchedulerSettings default_scheduler_settings
;
616 StateMachine
state(default_scheduler_settings
);
618 state
.UpdateState(state
.NextAction());
619 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
620 state
.SetVisible(true);
621 state
.SetCanDraw(true);
622 state
.SetNeedsRedraw(true);
624 // Draw the first frame.
625 EXPECT_TRUE(state
.BeginFrameNeeded());
626 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
627 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
628 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
630 state
.OnBeginImplFrameDeadline();
631 EXPECT_ACTION_UPDATE_STATE(
632 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
633 state
.DidSwapBuffers();
634 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
635 state
.DidSwapBuffersComplete();
636 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
638 // Before the next BeginImplFrame, set needs redraw again.
639 // This should not redraw until the next BeginImplFrame.
640 state
.SetNeedsRedraw(true);
641 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
643 // Move to another frame. This should now draw.
644 EXPECT_TRUE(state
.BeginFrameNeeded());
645 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
647 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
648 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
650 state
.OnBeginImplFrameDeadline();
651 EXPECT_ACTION_UPDATE_STATE(
652 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
653 state
.DidSwapBuffers();
654 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
655 state
.DidSwapBuffersComplete();
656 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
658 // We just swapped, so we should proactively request another BeginImplFrame.
659 EXPECT_TRUE(state
.BeginFrameNeeded());
662 TEST(SchedulerStateMachineTest
, TestNextActionDrawsOnBeginImplFrame
) {
663 SchedulerSettings default_scheduler_settings
;
665 // When not in BeginImplFrame deadline, or in BeginImplFrame deadline
666 // but not visible, don't draw.
667 size_t num_commit_states
=
668 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
669 size_t num_begin_impl_frame_states
=
670 sizeof(all_begin_impl_frame_states
) /
671 sizeof(SchedulerStateMachine::BeginImplFrameState
);
672 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
673 for (size_t j
= 0; j
< num_begin_impl_frame_states
; ++j
) {
674 StateMachine
state(default_scheduler_settings
);
676 state
.UpdateState(state
.NextAction());
677 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
678 state
.SetCommitState(all_commit_states
[i
]);
679 state
.SetBeginImplFrameState(all_begin_impl_frame_states
[j
]);
681 (all_begin_impl_frame_states
[j
] !=
682 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
683 state
.SetVisible(visible
);
685 // Case 1: needs_commit=false
686 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
689 // Case 2: needs_commit=true
690 state
.SetNeedsCommit();
691 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
697 // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw
698 // except if we're ready to commit, in which case we expect a commit first.
699 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
700 StateMachine
state(default_scheduler_settings
);
702 state
.UpdateState(state
.NextAction());
703 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
704 state
.SetCanDraw(true);
705 state
.SetCommitState(all_commit_states
[i
]);
706 state
.SetBeginImplFrameState(
707 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
709 state
.SetNeedsRedraw(true);
710 state
.SetVisible(true);
712 SchedulerStateMachine::Action expected_action
;
713 if (all_commit_states
[i
] ==
714 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
) {
715 expected_action
= SchedulerStateMachine::ACTION_COMMIT
;
717 expected_action
= SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
;
718 EXPECT_EQ(state
.NextAction(), SchedulerStateMachine::ACTION_ANIMATE
)
720 state
.UpdateState(state
.NextAction());
723 // Case 1: needs_commit=false.
724 EXPECT_EQ(state
.NextAction(), expected_action
) << *state
.AsValue();
726 // Case 2: needs_commit=true.
727 state
.SetNeedsCommit();
728 EXPECT_EQ(state
.NextAction(), expected_action
) << *state
.AsValue();
732 TEST(SchedulerStateMachineTest
, TestNoCommitStatesRedrawWhenInvisible
) {
733 SchedulerSettings default_scheduler_settings
;
735 size_t num_commit_states
=
736 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
737 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
738 // There shouldn't be any drawing regardless of BeginImplFrame.
739 for (size_t j
= 0; j
< 2; ++j
) {
740 StateMachine
state(default_scheduler_settings
);
742 state
.UpdateState(state
.NextAction());
743 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
744 state
.SetCommitState(all_commit_states
[i
]);
745 state
.SetVisible(false);
746 state
.SetNeedsRedraw(true);
748 state
.SetBeginImplFrameState(
749 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
752 // Case 1: needs_commit=false.
753 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
756 // Case 2: needs_commit=true.
757 state
.SetNeedsCommit();
758 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
765 TEST(SchedulerStateMachineTest
, TestCanRedraw_StopsDraw
) {
766 SchedulerSettings default_scheduler_settings
;
768 size_t num_commit_states
=
769 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
770 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
771 // There shouldn't be any drawing regardless of BeginImplFrame.
772 for (size_t j
= 0; j
< 2; ++j
) {
773 StateMachine
state(default_scheduler_settings
);
775 state
.UpdateState(state
.NextAction());
776 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
777 state
.SetCommitState(all_commit_states
[i
]);
778 state
.SetVisible(false);
779 state
.SetNeedsRedraw(true);
781 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
783 state
.SetCanDraw(false);
784 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
790 TEST(SchedulerStateMachineTest
,
791 TestCanRedrawWithWaitingForFirstDrawMakesProgress
) {
792 SchedulerSettings default_scheduler_settings
;
793 StateMachine
state(default_scheduler_settings
);
795 state
.UpdateState(state
.NextAction());
796 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
798 state
.SetActiveTreeNeedsFirstDraw(true);
799 state
.SetNeedsCommit();
800 state
.SetNeedsRedraw(true);
801 state
.SetVisible(true);
802 state
.SetCanDraw(false);
803 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
804 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
805 EXPECT_ACTION_UPDATE_STATE(
806 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
807 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
808 state
.NotifyBeginMainFrameStarted();
809 state
.NotifyReadyToCommit();
810 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
811 state
.OnBeginImplFrameDeadline();
812 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
813 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
816 void TestSetNeedsCommitIsNotLost(bool main_frame_before_draw_enabled
) {
817 SchedulerSettings scheduler_settings
;
818 scheduler_settings
.main_frame_before_draw_enabled
=
819 main_frame_before_draw_enabled
;
820 StateMachine
state(scheduler_settings
);
822 state
.UpdateState(state
.NextAction());
823 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
824 state
.SetNeedsCommit();
825 state
.SetVisible(true);
826 state
.SetCanDraw(true);
828 EXPECT_TRUE(state
.BeginFrameNeeded());
831 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
832 EXPECT_ACTION_UPDATE_STATE(
833 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
834 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
835 state
.CommitState());
837 // Now, while the frame is in progress, set another commit.
838 state
.SetNeedsCommit();
839 EXPECT_TRUE(state
.NeedsCommit());
841 // Let the frame finish.
842 state
.NotifyBeginMainFrameStarted();
843 state
.NotifyReadyToCommit();
844 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
845 state
.CommitState());
847 // Expect to commit regardless of BeginImplFrame state.
848 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
849 state
.begin_impl_frame_state());
850 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
852 state
.OnBeginImplFrameDeadlinePending();
853 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
854 state
.begin_impl_frame_state());
855 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
857 state
.OnBeginImplFrameDeadline();
858 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
,
859 state
.begin_impl_frame_state());
860 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
862 state
.OnBeginImplFrameIdle();
863 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
864 state
.begin_impl_frame_state());
865 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
867 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
868 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
869 state
.begin_impl_frame_state());
870 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
872 // Finish the commit, then make sure we start the next commit immediately
873 // and draw on the next BeginImplFrame.
874 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
875 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
876 if (main_frame_before_draw_enabled
) {
877 EXPECT_ACTION_UPDATE_STATE(
878 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
880 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
882 state
.OnBeginImplFrameDeadline();
884 EXPECT_TRUE(state
.active_tree_needs_first_draw());
885 EXPECT_ACTION_UPDATE_STATE(
886 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
887 state
.DidSwapBuffers();
888 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
889 state
.DidSwapBuffersComplete();
890 if (!main_frame_before_draw_enabled
) {
891 EXPECT_ACTION_UPDATE_STATE(
892 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
894 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
897 TEST(SchedulerStateMachineTest
, TestSetNeedsCommitIsNotLost
) {
898 bool main_frame_before_draw_enabled
= false;
899 TestSetNeedsCommitIsNotLost(main_frame_before_draw_enabled
);
902 TEST(SchedulerStateMachineTest
, TestSetNeedsCommitIsNotLost_CommitBeforeDraw
) {
903 bool main_frame_before_draw_enabled
= true;
904 TestSetNeedsCommitIsNotLost(main_frame_before_draw_enabled
);
907 TEST(SchedulerStateMachineTest
, TestFullCycle
) {
908 SchedulerSettings default_scheduler_settings
;
909 StateMachine
state(default_scheduler_settings
);
911 state
.UpdateState(state
.NextAction());
912 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
913 state
.SetVisible(true);
914 state
.SetCanDraw(true);
916 // Start clean and set commit.
917 state
.SetNeedsCommit();
920 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
921 EXPECT_ACTION_UPDATE_STATE(
922 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
923 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
924 state
.CommitState());
925 EXPECT_FALSE(state
.NeedsCommit());
926 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
928 // Tell the scheduler the frame finished.
929 state
.NotifyBeginMainFrameStarted();
930 state
.NotifyReadyToCommit();
931 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
932 state
.CommitState());
935 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
936 EXPECT_TRUE(state
.active_tree_needs_first_draw());
937 EXPECT_TRUE(state
.needs_redraw());
939 // Expect to do nothing until BeginImplFrame deadline
940 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
942 // At BeginImplFrame deadline, draw.
943 state
.OnBeginImplFrameDeadline();
944 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
945 EXPECT_ACTION_UPDATE_STATE(
946 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
947 state
.DidSwapBuffers();
948 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
949 state
.DidSwapBuffersComplete();
951 // Should be synchronized, no draw needed, no action needed.
952 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
953 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
954 EXPECT_FALSE(state
.needs_redraw());
957 TEST(SchedulerStateMachineTest
, TestFullCycleWithCommitRequestInbetween
) {
958 SchedulerSettings default_scheduler_settings
;
959 StateMachine
state(default_scheduler_settings
);
961 state
.UpdateState(state
.NextAction());
962 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
963 state
.SetVisible(true);
964 state
.SetCanDraw(true);
966 // Start clean and set commit.
967 state
.SetNeedsCommit();
970 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
971 EXPECT_ACTION_UPDATE_STATE(
972 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
973 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
974 state
.CommitState());
975 EXPECT_FALSE(state
.NeedsCommit());
976 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
978 // Request another commit while the commit is in flight.
979 state
.SetNeedsCommit();
980 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
982 // Tell the scheduler the frame finished.
983 state
.NotifyBeginMainFrameStarted();
984 state
.NotifyReadyToCommit();
985 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
986 state
.CommitState());
989 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
990 EXPECT_TRUE(state
.active_tree_needs_first_draw());
991 EXPECT_TRUE(state
.needs_redraw());
993 // Expect to do nothing until BeginImplFrame deadline.
994 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
996 // At BeginImplFrame deadline, draw.
997 state
.OnBeginImplFrameDeadline();
998 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
999 EXPECT_ACTION_UPDATE_STATE(
1000 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1001 state
.DidSwapBuffers();
1002 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
1003 state
.DidSwapBuffersComplete();
1005 // Should be synchronized, no draw needed, no action needed.
1006 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1007 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1008 EXPECT_FALSE(state
.needs_redraw());
1010 // Next BeginImplFrame should initiate second commit.
1011 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1012 EXPECT_ACTION_UPDATE_STATE(
1013 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1016 TEST(SchedulerStateMachineTest
, TestRequestCommitInvisible
) {
1017 SchedulerSettings default_scheduler_settings
;
1018 StateMachine
state(default_scheduler_settings
);
1019 state
.SetCanStart();
1020 state
.UpdateState(state
.NextAction());
1021 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1022 state
.SetNeedsCommit();
1023 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1026 TEST(SchedulerStateMachineTest
, TestGoesInvisibleBeforeFinishCommit
) {
1027 SchedulerSettings default_scheduler_settings
;
1028 StateMachine
state(default_scheduler_settings
);
1029 state
.SetCanStart();
1030 state
.UpdateState(state
.NextAction());
1031 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1032 state
.SetVisible(true);
1033 state
.SetCanDraw(true);
1035 // Start clean and set commit.
1036 state
.SetNeedsCommit();
1038 // Begin the frame while visible.
1039 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1040 EXPECT_ACTION_UPDATE_STATE(
1041 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1042 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1043 state
.CommitState());
1044 EXPECT_FALSE(state
.NeedsCommit());
1045 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1047 // Become invisible and abort BeginMainFrame.
1048 state
.SetVisible(false);
1049 state
.BeginMainFrameAborted(false);
1051 // We should now be back in the idle state as if we never started the frame.
1052 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1053 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1055 // We shouldn't do anything on the BeginImplFrame deadline.
1056 state
.OnBeginImplFrameDeadline();
1057 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1059 // Become visible again.
1060 state
.SetVisible(true);
1062 // Although we have aborted on this frame and haven't cancelled the commit
1063 // (i.e. need another), don't send another BeginMainFrame yet.
1064 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1065 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1066 EXPECT_TRUE(state
.NeedsCommit());
1068 // Start a new frame.
1069 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1070 EXPECT_ACTION_UPDATE_STATE(
1071 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1073 // We should be starting the commit now.
1074 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1075 state
.CommitState());
1076 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1079 TEST(SchedulerStateMachineTest
, AbortBeginMainFrameAndCancelCommit
) {
1080 SchedulerSettings default_scheduler_settings
;
1081 StateMachine
state(default_scheduler_settings
);
1082 state
.SetCanStart();
1083 state
.UpdateState(state
.NextAction());
1084 state
.DidCreateAndInitializeOutputSurface();
1085 state
.SetVisible(true);
1086 state
.SetCanDraw(true);
1088 // Get into a begin frame / commit state.
1089 state
.SetNeedsCommit();
1091 EXPECT_ACTION_UPDATE_STATE(
1092 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1093 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1094 state
.CommitState());
1095 EXPECT_FALSE(state
.NeedsCommit());
1096 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1098 // Abort the commit, cancelling future commits.
1099 state
.BeginMainFrameAborted(true);
1101 // Verify that another commit doesn't start on the same frame.
1102 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1103 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1104 EXPECT_FALSE(state
.NeedsCommit());
1106 // Start a new frame; draw because this is the first frame since output
1108 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1109 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1110 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1111 state
.OnBeginImplFrameDeadline();
1112 EXPECT_ACTION_UPDATE_STATE(
1113 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1114 state
.DidSwapBuffers();
1115 state
.DidSwapBuffersComplete();
1117 // Verify another commit doesn't start on another frame either.
1118 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1119 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1120 EXPECT_FALSE(state
.NeedsCommit());
1122 // Verify another commit can start if requested, though.
1123 state
.SetNeedsCommit();
1124 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1125 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
,
1126 state
.NextAction());
1129 TEST(SchedulerStateMachineTest
,
1130 AbortBeginMainFrameAndCancelCommitWhenInvisible
) {
1131 SchedulerSettings default_scheduler_settings
;
1132 StateMachine
state(default_scheduler_settings
);
1133 state
.SetCanStart();
1134 state
.UpdateState(state
.NextAction());
1135 state
.DidCreateAndInitializeOutputSurface();
1136 state
.SetVisible(true);
1137 state
.SetCanDraw(true);
1139 // Get into a begin frame / commit state.
1140 state
.SetNeedsCommit();
1142 EXPECT_ACTION_UPDATE_STATE(
1143 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1144 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1145 state
.CommitState());
1146 EXPECT_FALSE(state
.NeedsCommit());
1147 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1149 // Become invisible and abort BeginMainFrame.
1150 state
.SetVisible(false);
1151 state
.BeginMainFrameAborted(true);
1153 // Verify that another commit doesn't start on the same frame.
1154 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1155 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1156 EXPECT_FALSE(state
.NeedsCommit());
1158 // Become visible and start a new frame.
1159 state
.SetVisible(true);
1160 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1161 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1162 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1164 // Draw because this is the first frame since output surface init'd.
1165 state
.OnBeginImplFrameDeadline();
1166 EXPECT_ACTION_UPDATE_STATE(
1167 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1168 state
.DidSwapBuffers();
1169 state
.DidSwapBuffersComplete();
1171 // Verify another commit doesn't start on another frame either.
1172 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1173 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1174 EXPECT_FALSE(state
.NeedsCommit());
1176 // Verify another commit can start if requested, though.
1177 state
.SetNeedsCommit();
1178 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1179 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
,
1180 state
.NextAction());
1183 TEST(SchedulerStateMachineTest
,
1184 AbortBeginMainFrameAndRequestCommitWhenInvisible
) {
1185 SchedulerSettings default_scheduler_settings
;
1186 StateMachine
state(default_scheduler_settings
);
1187 state
.SetCanStart();
1188 state
.UpdateState(state
.NextAction());
1189 state
.DidCreateAndInitializeOutputSurface();
1190 state
.SetVisible(true);
1191 state
.SetCanDraw(true);
1193 // Get into a begin frame / commit state.
1194 state
.SetNeedsCommit();
1196 EXPECT_ACTION_UPDATE_STATE(
1197 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1198 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1199 state
.CommitState());
1200 EXPECT_FALSE(state
.NeedsCommit());
1201 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1203 // Become invisible and abort BeginMainFrame.
1204 state
.SetVisible(false);
1205 state
.BeginMainFrameAborted(true);
1207 // Verify that another commit doesn't start on the same frame.
1208 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1209 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1210 EXPECT_FALSE(state
.NeedsCommit());
1212 // Asking for a commit while not visible won't make it happen.
1213 state
.SetNeedsCommit();
1214 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1215 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1216 EXPECT_TRUE(state
.NeedsCommit());
1218 // Become visible but nothing happens until the next frame.
1219 state
.SetVisible(true);
1220 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1221 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1222 EXPECT_TRUE(state
.NeedsCommit());
1224 // We should get that commit when we begin the next frame.
1225 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1226 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1227 EXPECT_ACTION_UPDATE_STATE(
1228 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1231 TEST(SchedulerStateMachineTest
,
1232 AbortBeginMainFrameAndRequestCommitAndBeginImplFrameWhenInvisible
) {
1233 SchedulerSettings default_scheduler_settings
;
1234 StateMachine
state(default_scheduler_settings
);
1235 state
.SetCanStart();
1236 state
.UpdateState(state
.NextAction());
1237 state
.DidCreateAndInitializeOutputSurface();
1238 state
.SetVisible(true);
1239 state
.SetCanDraw(true);
1241 // Get into a begin frame / commit state.
1242 state
.SetNeedsCommit();
1244 EXPECT_ACTION_UPDATE_STATE(
1245 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1246 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1247 state
.CommitState());
1248 EXPECT_FALSE(state
.NeedsCommit());
1249 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1251 // Become invisible and abort BeginMainFrame.
1252 state
.SetVisible(false);
1253 state
.BeginMainFrameAborted(true);
1255 // Asking for a commit while not visible won't make it happen.
1256 state
.SetNeedsCommit();
1257 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1258 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1259 EXPECT_TRUE(state
.NeedsCommit());
1261 // Begin a frame when not visible, the scheduler animates but does not commit.
1262 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1263 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1264 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1265 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1266 EXPECT_TRUE(state
.NeedsCommit());
1268 // Become visible and the requested commit happens immediately.
1269 state
.SetVisible(true);
1270 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1271 EXPECT_ACTION_UPDATE_STATE(
1272 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1275 TEST(SchedulerStateMachineTest
, TestFirstContextCreation
) {
1276 SchedulerSettings default_scheduler_settings
;
1277 StateMachine
state(default_scheduler_settings
);
1278 state
.SetCanStart();
1279 state
.SetVisible(true);
1280 state
.SetCanDraw(true);
1282 EXPECT_ACTION_UPDATE_STATE(
1283 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1284 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1285 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1287 // Check that the first init does not SetNeedsCommit.
1288 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1289 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1290 state
.OnBeginImplFrameDeadline();
1291 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1293 // Check that a needs commit initiates a BeginMainFrame.
1294 state
.SetNeedsCommit();
1295 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1296 EXPECT_ACTION_UPDATE_STATE(
1297 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1300 TEST(SchedulerStateMachineTest
, TestContextLostWhenCompletelyIdle
) {
1301 SchedulerSettings default_scheduler_settings
;
1302 StateMachine
state(default_scheduler_settings
);
1303 state
.SetCanStart();
1304 state
.UpdateState(state
.NextAction());
1305 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1307 state
.SetVisible(true);
1308 state
.SetCanDraw(true);
1310 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1311 state
.NextAction());
1312 state
.DidLoseOutputSurface();
1314 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1315 state
.NextAction());
1316 state
.UpdateState(state
.NextAction());
1318 // Once context recreation begins, nothing should happen.
1319 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1321 // Recreate the context.
1322 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1324 // When the context is recreated, we should begin a commit.
1325 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1326 EXPECT_ACTION_UPDATE_STATE(
1327 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1330 TEST(SchedulerStateMachineTest
,
1331 TestContextLostWhenIdleAndCommitRequestedWhileRecreating
) {
1332 SchedulerSettings default_scheduler_settings
;
1333 StateMachine
state(default_scheduler_settings
);
1334 state
.SetCanStart();
1335 state
.UpdateState(state
.NextAction());
1336 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1337 state
.SetVisible(true);
1338 state
.SetCanDraw(true);
1340 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1341 state
.NextAction());
1342 state
.DidLoseOutputSurface();
1344 EXPECT_ACTION_UPDATE_STATE(
1345 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1346 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1348 // Once context recreation begins, nothing should happen.
1349 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1350 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1351 state
.OnBeginImplFrameDeadline();
1352 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1354 // While context is recreating, commits shouldn't begin.
1355 state
.SetNeedsCommit();
1356 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1357 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1358 state
.OnBeginImplFrameDeadline();
1359 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1361 // Recreate the context
1362 state
.DidCreateAndInitializeOutputSurface();
1363 EXPECT_FALSE(state
.RedrawPending());
1365 // When the context is recreated, we should begin a commit
1366 EXPECT_ACTION_UPDATE_STATE(
1367 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1368 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1369 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1370 state
.CommitState());
1372 state
.NotifyBeginMainFrameStarted();
1373 state
.NotifyReadyToCommit();
1374 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1375 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1376 // Finishing the first commit after initializing an output surface should
1377 // automatically cause a redraw.
1378 EXPECT_TRUE(state
.RedrawPending());
1380 // Once the context is recreated, whether we draw should be based on
1382 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1383 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1384 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1385 state
.OnBeginImplFrameDeadline();
1386 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
1387 state
.NextAction());
1388 state
.SetCanDraw(false);
1389 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
,
1390 state
.NextAction());
1391 state
.SetCanDraw(true);
1392 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
1393 state
.NextAction());
1396 TEST(SchedulerStateMachineTest
, TestContextLostWhileCommitInProgress
) {
1397 SchedulerSettings scheduler_settings
;
1398 StateMachine
state(scheduler_settings
);
1399 state
.SetCanStart();
1400 state
.UpdateState(state
.NextAction());
1401 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1402 state
.SetVisible(true);
1403 state
.SetCanDraw(true);
1405 // Get a commit in flight.
1406 state
.SetNeedsCommit();
1408 // Set damage and expect a draw.
1409 state
.SetNeedsRedraw(true);
1410 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1411 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1412 EXPECT_ACTION_UPDATE_STATE(
1413 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1414 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1415 state
.OnBeginImplFrameDeadline();
1416 EXPECT_ACTION_UPDATE_STATE(
1417 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1418 state
.DidSwapBuffers();
1419 state
.DidSwapBuffersComplete();
1420 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1422 // Cause a lost context while the BeginMainFrame is in flight.
1423 state
.DidLoseOutputSurface();
1425 // Ask for another draw. Expect nothing happens.
1426 state
.SetNeedsRedraw(true);
1427 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1429 // Finish the frame, and commit.
1430 state
.NotifyBeginMainFrameStarted();
1431 state
.NotifyReadyToCommit();
1432 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1434 // We will abort the draw when the output surface is lost if we are
1435 // waiting for the first draw to unblock the main thread.
1436 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1437 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1439 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1440 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
1441 state
.begin_impl_frame_state());
1442 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1443 state
.NextAction());
1445 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1446 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
1447 state
.begin_impl_frame_state());
1448 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1450 state
.OnBeginImplFrameDeadlinePending();
1451 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
1452 state
.begin_impl_frame_state());
1453 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1455 state
.OnBeginImplFrameDeadline();
1456 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
,
1457 state
.begin_impl_frame_state());
1458 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1461 TEST(SchedulerStateMachineTest
,
1462 TestContextLostWhileCommitInProgressAndAnotherCommitRequested
) {
1463 SchedulerSettings scheduler_settings
;
1464 StateMachine
state(scheduler_settings
);
1465 state
.SetCanStart();
1466 state
.UpdateState(state
.NextAction());
1467 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1468 state
.SetVisible(true);
1469 state
.SetCanDraw(true);
1471 // Get a commit in flight.
1472 state
.SetNeedsCommit();
1473 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1475 // Set damage and expect a draw.
1476 state
.SetNeedsRedraw(true);
1477 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1478 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1479 EXPECT_ACTION_UPDATE_STATE(
1480 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1481 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1482 state
.OnBeginImplFrameDeadline();
1483 EXPECT_ACTION_UPDATE_STATE(
1484 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1485 state
.DidSwapBuffers();
1486 state
.DidSwapBuffersComplete();
1487 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1489 // Cause a lost context while the BeginMainFrame is in flight.
1490 state
.DidLoseOutputSurface();
1492 // Ask for another draw and also set needs commit. Expect nothing happens.
1493 state
.SetNeedsRedraw(true);
1494 state
.SetNeedsCommit();
1495 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1497 // Finish the frame, and commit.
1498 state
.NotifyBeginMainFrameStarted();
1499 state
.NotifyReadyToCommit();
1500 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1501 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1503 // Because the output surface is missing, we expect the draw to abort.
1504 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1506 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1507 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
1508 state
.begin_impl_frame_state());
1509 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1510 state
.NextAction());
1512 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1513 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
1514 state
.begin_impl_frame_state());
1515 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1517 state
.OnBeginImplFrameDeadlinePending();
1518 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
1519 state
.begin_impl_frame_state());
1520 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1522 state
.OnBeginImplFrameDeadline();
1523 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
,
1524 state
.begin_impl_frame_state());
1525 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1527 state
.OnBeginImplFrameIdle();
1528 EXPECT_ACTION_UPDATE_STATE(
1529 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1531 // After we get a new output surface, the commit flow should start.
1532 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1533 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1534 EXPECT_ACTION_UPDATE_STATE(
1535 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1536 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1537 state
.NotifyBeginMainFrameStarted();
1538 state
.NotifyReadyToCommit();
1539 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1540 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1541 state
.OnBeginImplFrameDeadline();
1542 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1543 EXPECT_ACTION_UPDATE_STATE(
1544 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1545 state
.DidSwapBuffers();
1546 state
.DidSwapBuffersComplete();
1547 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1550 TEST(SchedulerStateMachineTest
, DontDrawBeforeCommitAfterLostOutputSurface
) {
1551 SchedulerSettings default_scheduler_settings
;
1552 StateMachine
state(default_scheduler_settings
);
1553 state
.SetCanStart();
1554 state
.UpdateState(state
.NextAction());
1555 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1556 state
.SetVisible(true);
1557 state
.SetCanDraw(true);
1559 state
.SetNeedsRedraw(true);
1561 // Cause a lost output surface, and restore it.
1562 state
.DidLoseOutputSurface();
1563 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1564 state
.NextAction());
1565 state
.UpdateState(state
.NextAction());
1566 state
.DidCreateAndInitializeOutputSurface();
1568 EXPECT_FALSE(state
.RedrawPending());
1569 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1570 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
,
1571 state
.NextAction());
1574 TEST(SchedulerStateMachineTest
,
1575 TestPendingActivationsShouldBeForcedAfterLostOutputSurface
) {
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 state
.SetCommitState(
1586 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1588 // Cause a lost context.
1589 state
.DidLoseOutputSurface();
1591 state
.NotifyBeginMainFrameStarted();
1592 state
.NotifyReadyToCommit();
1593 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1595 EXPECT_TRUE(state
.PendingActivationsShouldBeForced());
1596 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1598 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1599 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1602 TEST(SchedulerStateMachineTest
, TestNoBeginMainFrameWhenInvisible
) {
1603 SchedulerSettings default_scheduler_settings
;
1604 StateMachine
state(default_scheduler_settings
);
1605 state
.SetCanStart();
1606 state
.UpdateState(state
.NextAction());
1607 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1608 state
.SetVisible(false);
1609 state
.SetNeedsCommit();
1610 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1613 TEST(SchedulerStateMachineTest
, TestFinishCommitWhenCommitInProgress
) {
1614 SchedulerSettings default_scheduler_settings
;
1615 StateMachine
state(default_scheduler_settings
);
1616 state
.SetCanStart();
1617 state
.UpdateState(state
.NextAction());
1618 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1619 state
.SetVisible(false);
1620 state
.SetCommitState(
1621 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1622 state
.SetNeedsCommit();
1624 state
.NotifyBeginMainFrameStarted();
1625 state
.NotifyReadyToCommit();
1626 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
1627 state
.UpdateState(state
.NextAction());
1629 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1630 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1633 TEST(SchedulerStateMachineTest
, TestInitialActionsWhenContextLost
) {
1634 SchedulerSettings default_scheduler_settings
;
1635 StateMachine
state(default_scheduler_settings
);
1636 state
.SetCanStart();
1637 state
.UpdateState(state
.NextAction());
1638 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1639 state
.SetVisible(true);
1640 state
.SetCanDraw(true);
1641 state
.SetNeedsCommit();
1642 state
.DidLoseOutputSurface();
1644 // When we are visible, we normally want to begin output surface creation
1645 // as soon as possible.
1646 EXPECT_ACTION_UPDATE_STATE(
1647 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1649 state
.DidCreateAndInitializeOutputSurface();
1650 EXPECT_EQ(state
.output_surface_state(),
1651 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT
);
1653 // We should not send a BeginMainFrame when we are invisible, even if we've
1654 // lost the output surface and are trying to get the first commit, since the
1655 // main thread will just abort anyway.
1656 state
.SetVisible(false);
1657 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction())
1658 << *state
.AsValue();
1661 TEST(SchedulerStateMachineTest
, ReportIfNotDrawing
) {
1662 SchedulerSettings default_scheduler_settings
;
1663 StateMachine
state(default_scheduler_settings
);
1664 state
.SetCanStart();
1665 state
.UpdateState(state
.NextAction());
1666 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1668 state
.SetCanDraw(true);
1669 state
.SetVisible(true);
1670 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1672 state
.SetCanDraw(false);
1673 state
.SetVisible(true);
1674 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1676 state
.SetCanDraw(true);
1677 state
.SetVisible(false);
1678 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1680 state
.SetCanDraw(false);
1681 state
.SetVisible(false);
1682 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1684 state
.SetCanDraw(true);
1685 state
.SetVisible(true);
1686 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1689 TEST(SchedulerStateMachineTest
, TestTriggerDeadlineEarlyAfterAbortedCommit
) {
1690 SchedulerSettings settings
;
1691 settings
.impl_side_painting
= true;
1692 StateMachine
state(settings
);
1693 state
.SetCanStart();
1694 state
.UpdateState(state
.NextAction());
1695 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1696 state
.SetVisible(true);
1697 state
.SetCanDraw(true);
1699 // This test mirrors what happens during the first frame of a scroll gesture.
1700 // First we get the input event and a BeginFrame.
1701 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1703 // As a response the compositor requests a redraw and a commit to tell the
1704 // main thread about the new scroll offset.
1705 state
.SetNeedsRedraw(true);
1706 state
.SetNeedsCommit();
1708 // We should start the commit normally.
1709 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1710 EXPECT_ACTION_UPDATE_STATE(
1711 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1712 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1714 // Since only the scroll offset changed, the main thread will abort the
1716 state
.BeginMainFrameAborted(true);
1718 // Since the commit was aborted, we should draw right away instead of waiting
1719 // for the deadline.
1720 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1723 void FinishPreviousCommitAndDrawWithoutExitingDeadline(
1724 StateMachine
* state_ptr
) {
1725 // Gross, but allows us to use macros below.
1726 StateMachine
& state
= *state_ptr
;
1728 state
.NotifyBeginMainFrameStarted();
1729 state
.NotifyReadyToCommit();
1730 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1731 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1732 state
.NotifyReadyToActivate();
1733 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE
);
1734 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1736 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1737 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1738 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1740 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1741 state
.OnBeginImplFrameDeadline();
1742 EXPECT_ACTION_UPDATE_STATE(
1743 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1744 state
.DidSwapBuffers();
1747 TEST(SchedulerStateMachineTest
, TestSmoothnessTakesPriority
) {
1748 SchedulerSettings settings
;
1749 settings
.impl_side_painting
= true;
1750 StateMachine
state(settings
);
1751 state
.SetCanStart();
1752 state
.UpdateState(state
.NextAction());
1753 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1754 state
.SetVisible(true);
1755 state
.SetCanDraw(true);
1757 // This test ensures that impl-draws are prioritized over main thread updates
1758 // in prefer smoothness mode.
1759 state
.SetNeedsRedraw(true);
1760 state
.SetNeedsCommit();
1761 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1762 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1763 EXPECT_ACTION_UPDATE_STATE(
1764 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1765 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1767 // Verify the deadline is not triggered early until we enter
1768 // prefer smoothness mode.
1769 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1770 state
.SetSmoothnessTakesPriority(true);
1771 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1773 // Trigger the deadline.
1774 state
.OnBeginImplFrameDeadline();
1775 EXPECT_ACTION_UPDATE_STATE(
1776 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1777 state
.DidSwapBuffers();
1778 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1779 state
.DidSwapBuffersComplete();
1781 // Request a new commit and finish the previous one.
1782 state
.SetNeedsCommit();
1783 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1784 EXPECT_ACTION_UPDATE_STATE(
1785 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1786 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1787 state
.DidSwapBuffersComplete();
1788 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1790 // Finish the previous commit and draw it.
1791 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1792 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1794 // Verify we do not send another BeginMainFrame if was are swap throttled
1795 // and did not just swap.
1796 state
.SetNeedsCommit();
1797 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1798 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1799 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1800 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1801 state
.OnBeginImplFrameDeadline();
1802 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1805 TEST(SchedulerStateMachineTest
, TestTriggerDeadlineEarlyOnLostOutputSurface
) {
1806 SchedulerSettings default_scheduler_settings
;
1807 StateMachine
state(default_scheduler_settings
);
1808 state
.SetCanStart();
1809 state
.UpdateState(state
.NextAction());
1810 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1811 state
.SetVisible(true);
1812 state
.SetCanDraw(true);
1814 state
.SetNeedsCommit();
1816 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1817 EXPECT_ACTION_UPDATE_STATE(
1818 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1819 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1820 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1822 state
.DidLoseOutputSurface();
1823 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1824 // The deadline should be triggered immediately when output surface is lost.
1825 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1828 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimate
) {
1829 SchedulerSettings settings
;
1830 settings
.impl_side_painting
= true;
1831 StateMachine
state(settings
);
1832 state
.SetCanStart();
1833 state
.UpdateState(state
.NextAction());
1834 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1835 state
.SetVisible(true);
1836 state
.SetCanDraw(true);
1838 // Test requesting an animation that, when run, causes us to draw.
1839 state
.SetNeedsAnimate();
1840 EXPECT_TRUE(state
.BeginFrameNeeded());
1841 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1843 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1844 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1846 state
.OnBeginImplFrameDeadlinePending();
1847 state
.OnBeginImplFrameDeadline();
1848 EXPECT_ACTION_UPDATE_STATE(
1849 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1852 TEST(SchedulerStateMachineTest
, TestAnimateBeforeCommit
) {
1853 SchedulerSettings settings
;
1854 settings
.impl_side_painting
= true;
1855 StateMachine
state(settings
);
1856 state
.SetCanStart();
1857 state
.UpdateState(state
.NextAction());
1858 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1859 state
.SetVisible(true);
1860 state
.SetCanDraw(true);
1862 // Check that animations are updated before we start a commit.
1863 state
.SetNeedsAnimate();
1864 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1865 state
.SetNeedsCommit();
1866 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1867 EXPECT_TRUE(state
.BeginFrameNeeded());
1869 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1870 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1871 EXPECT_ACTION_UPDATE_STATE(
1872 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1874 state
.OnBeginImplFrameDeadlinePending();
1875 state
.OnBeginImplFrameDeadline();
1876 EXPECT_ACTION_UPDATE_STATE(
1877 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1880 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimateAfterAnimate
) {
1881 SchedulerSettings settings
;
1882 settings
.impl_side_painting
= true;
1883 StateMachine
state(settings
);
1884 state
.SetCanStart();
1885 state
.UpdateState(state
.NextAction());
1886 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1887 state
.SetVisible(true);
1888 state
.SetCanDraw(true);
1890 // Test requesting an animation after we have already animated during this
1892 state
.SetNeedsRedraw(true);
1893 EXPECT_TRUE(state
.BeginFrameNeeded());
1894 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1896 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1897 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1899 state
.SetNeedsAnimate();
1900 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1902 state
.OnBeginImplFrameDeadline();
1903 EXPECT_ACTION_UPDATE_STATE(
1904 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);