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(
236 SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE
);
237 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
238 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
239 EXPECT_EQ(state
.CommitState(),
240 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
);
242 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
243 state
.OnBeginImplFrameDeadline();
244 EXPECT_ACTION_UPDATE_STATE(
245 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
246 state
.DidSwapBuffers();
247 state
.DidSwapBuffersComplete();
248 EXPECT_EQ(state
.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE
);
249 EXPECT_ACTION_UPDATE_STATE(
250 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
251 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
252 EXPECT_EQ(state
.CommitState(),
253 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
255 state
.NotifyBeginMainFrameStarted();
256 state
.NotifyReadyToCommit();
257 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
258 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
259 EXPECT_EQ(state
.CommitState(),
260 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
);
263 // Explicitly test main_frame_before_activation_enabled = true
264 TEST(SchedulerStateMachineTest
, MainFrameBeforeActivationEnabled
) {
265 SchedulerSettings scheduler_settings
;
266 scheduler_settings
.impl_side_painting
= true;
267 scheduler_settings
.main_frame_before_activation_enabled
= true;
268 StateMachine
state(scheduler_settings
);
269 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
271 state
.UpdateState(state
.NextAction());
272 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
273 state
.SetNeedsRedraw(false);
274 state
.SetVisible(true);
275 state
.SetCanDraw(true);
276 state
.SetNeedsCommit();
278 EXPECT_TRUE(state
.BeginFrameNeeded());
280 // Commit to the pending tree.
281 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
282 EXPECT_ACTION_UPDATE_STATE(
283 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
284 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
286 state
.NotifyBeginMainFrameStarted();
287 state
.NotifyReadyToCommit();
288 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
289 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
290 EXPECT_EQ(state
.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE
);
292 state
.OnBeginImplFrameDeadline();
293 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
295 // Verify that the next commit starts while there is still a pending tree.
296 state
.SetNeedsCommit();
297 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
298 EXPECT_ACTION_UPDATE_STATE(
299 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
300 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
302 // Verify the pending commit doesn't overwrite the pending
303 // tree until the pending tree has been activated.
304 state
.NotifyBeginMainFrameStarted();
305 state
.NotifyReadyToCommit();
306 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
308 // Verify NotifyReadyToActivate unblocks activation, draw, and
309 // commit in that order.
310 state
.NotifyReadyToActivate();
311 EXPECT_ACTION_UPDATE_STATE(
312 SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE
);
313 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
315 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
316 state
.OnBeginImplFrameDeadline();
317 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
318 EXPECT_ACTION_UPDATE_STATE(
319 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
320 state
.DidSwapBuffers();
321 state
.DidSwapBuffersComplete();
322 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
323 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
324 EXPECT_EQ(state
.CommitState(), SchedulerStateMachine::COMMIT_STATE_IDLE
);
327 TEST(SchedulerStateMachineTest
,
328 TestFailedDrawForAnimationCheckerboardSetsNeedsCommitAndDoesNotDrawAgain
) {
329 SchedulerSettings default_scheduler_settings
;
330 StateMachine
state(default_scheduler_settings
);
332 state
.UpdateState(state
.NextAction());
333 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
334 state
.SetVisible(true);
335 state
.SetCanDraw(true);
336 state
.SetNeedsRedraw(true);
337 EXPECT_TRUE(state
.RedrawPending());
338 EXPECT_TRUE(state
.BeginFrameNeeded());
339 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
340 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
341 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
342 state
.OnBeginImplFrameDeadline();
344 // We're drawing now.
345 EXPECT_ACTION_UPDATE_STATE(
346 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
347 state
.DidSwapBuffers();
348 state
.DidSwapBuffersComplete();
349 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
351 EXPECT_FALSE(state
.RedrawPending());
352 EXPECT_FALSE(state
.CommitPending());
354 // Failing the draw makes us require a commit.
355 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
356 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
357 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
358 EXPECT_ACTION_UPDATE_STATE(
359 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
360 EXPECT_TRUE(state
.RedrawPending());
361 EXPECT_TRUE(state
.CommitPending());
364 TEST(SchedulerStateMachineTest
, TestFailedDrawForMissingHighResNeedsCommit
) {
365 SchedulerSettings default_scheduler_settings
;
366 StateMachine
state(default_scheduler_settings
);
368 state
.UpdateState(state
.NextAction());
369 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
370 state
.SetVisible(true);
371 state
.SetCanDraw(true);
372 state
.SetNeedsRedraw(true);
373 EXPECT_TRUE(state
.RedrawPending());
374 EXPECT_TRUE(state
.BeginFrameNeeded());
376 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
377 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
378 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
379 state
.OnBeginImplFrameDeadline();
380 EXPECT_ACTION_UPDATE_STATE(
381 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
382 state
.DidSwapBuffers();
383 state
.DidSwapBuffersComplete();
384 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
385 EXPECT_FALSE(state
.RedrawPending());
386 EXPECT_FALSE(state
.CommitPending());
388 // Missing high res content requires a commit (but not a redraw)
389 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT
);
390 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
391 EXPECT_ACTION_UPDATE_STATE(
392 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
393 EXPECT_FALSE(state
.RedrawPending());
394 EXPECT_TRUE(state
.CommitPending());
397 TEST(SchedulerStateMachineTest
,
398 TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw
) {
399 SchedulerSettings default_scheduler_settings
;
400 StateMachine
state(default_scheduler_settings
);
402 state
.UpdateState(state
.NextAction());
403 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
405 state
.SetVisible(true);
406 state
.SetCanDraw(true);
407 state
.SetNeedsRedraw(true);
408 EXPECT_TRUE(state
.RedrawPending());
409 EXPECT_TRUE(state
.BeginFrameNeeded());
410 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
411 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
412 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
413 state
.OnBeginImplFrameDeadline();
415 // We're drawing now.
416 EXPECT_ACTION_UPDATE_STATE(
417 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
418 state
.DidSwapBuffers();
419 state
.DidSwapBuffersComplete();
420 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
421 EXPECT_FALSE(state
.RedrawPending());
422 EXPECT_FALSE(state
.CommitPending());
424 // While still in the same BeginMainFrame callback on the main thread,
425 // set needs redraw again. This should not redraw.
426 state
.SetNeedsRedraw(true);
427 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
429 // Failing the draw for animation checkerboards makes us require a commit.
430 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
431 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
432 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
433 EXPECT_ACTION_UPDATE_STATE(
434 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
435 EXPECT_TRUE(state
.RedrawPending());
438 void TestFailedDrawsEventuallyForceDrawAfterNextCommit(
439 bool main_frame_before_draw_enabled
) {
440 SchedulerSettings scheduler_settings
;
441 scheduler_settings
.main_frame_before_draw_enabled
=
442 main_frame_before_draw_enabled
;
443 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced_
= 1;
444 StateMachine
state(scheduler_settings
);
446 state
.UpdateState(state
.NextAction());
447 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
448 state
.SetVisible(true);
449 state
.SetCanDraw(true);
452 state
.SetNeedsCommit();
453 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
454 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
455 EXPECT_ACTION_UPDATE_STATE(
456 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
457 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
458 EXPECT_TRUE(state
.CommitPending());
460 // Then initiate a draw.
461 state
.SetNeedsRedraw(true);
462 state
.OnBeginImplFrameDeadline();
463 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
464 EXPECT_ACTION_UPDATE_STATE(
465 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
468 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
469 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
470 EXPECT_TRUE(state
.BeginFrameNeeded());
471 EXPECT_TRUE(state
.RedrawPending());
472 // But the commit is ongoing.
473 EXPECT_TRUE(state
.CommitPending());
475 // Finish the commit. Note, we should not yet be forcing a draw, but should
476 // continue the commit as usual.
477 state
.NotifyBeginMainFrameStarted();
478 state
.NotifyReadyToCommit();
479 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
480 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
481 EXPECT_TRUE(state
.RedrawPending());
483 // The redraw should be forced at the end of the next BeginImplFrame.
484 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
485 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
486 if (main_frame_before_draw_enabled
) {
487 EXPECT_ACTION_UPDATE_STATE(
488 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
490 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
491 state
.OnBeginImplFrameDeadline();
492 EXPECT_ACTION_UPDATE_STATE(
493 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED
);
494 state
.DidSwapBuffers();
495 state
.DidSwapBuffersComplete();
498 TEST(SchedulerStateMachineTest
,
499 TestFailedDrawsEventuallyForceDrawAfterNextCommit
) {
500 bool main_frame_before_draw_enabled
= false;
501 TestFailedDrawsEventuallyForceDrawAfterNextCommit(
502 main_frame_before_draw_enabled
);
505 TEST(SchedulerStateMachineTest
,
506 TestFailedDrawsEventuallyForceDrawAfterNextCommit_CommitBeforeDraw
) {
507 bool main_frame_before_draw_enabled
= true;
508 TestFailedDrawsEventuallyForceDrawAfterNextCommit(
509 main_frame_before_draw_enabled
);
512 TEST(SchedulerStateMachineTest
, TestFailedDrawsDoNotRestartForcedDraw
) {
513 SchedulerSettings scheduler_settings
;
515 scheduler_settings
.maximum_number_of_failed_draws_before_draw_is_forced_
=
517 scheduler_settings
.impl_side_painting
= true;
518 StateMachine
state(scheduler_settings
);
520 state
.UpdateState(state
.NextAction());
521 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
522 state
.SetVisible(true);
523 state
.SetCanDraw(true);
526 state
.SetNeedsCommit();
527 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
528 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
529 EXPECT_ACTION_UPDATE_STATE(
530 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
531 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
532 EXPECT_TRUE(state
.CommitPending());
534 // Then initiate a draw.
535 state
.SetNeedsRedraw(true);
536 state
.OnBeginImplFrameDeadline();
537 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
538 EXPECT_ACTION_UPDATE_STATE(
539 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
541 // Fail the draw enough times to force a redraw,
542 // then once more for good measure.
543 for (int i
= 0; i
< draw_limit
+ 1; ++i
)
544 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
545 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
546 EXPECT_TRUE(state
.BeginFrameNeeded());
547 EXPECT_TRUE(state
.RedrawPending());
548 // But the commit is ongoing.
549 EXPECT_TRUE(state
.CommitPending());
550 EXPECT_TRUE(state
.ForcedRedrawState() ==
551 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_COMMIT
);
553 state
.NotifyBeginMainFrameStarted();
554 state
.NotifyReadyToCommit();
555 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
556 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
557 EXPECT_TRUE(state
.RedrawPending());
558 EXPECT_FALSE(state
.CommitPending());
560 // Now force redraw should be in waiting for activation
561 EXPECT_TRUE(state
.ForcedRedrawState() ==
562 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
564 // After failing additional draws, we should still be in a forced
565 // redraw, but not back in WAITING_FOR_COMMIT.
566 for (int i
= 0; i
< draw_limit
+ 1; ++i
)
567 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
568 EXPECT_TRUE(state
.RedrawPending());
569 EXPECT_TRUE(state
.ForcedRedrawState() ==
570 SchedulerStateMachine::FORCED_REDRAW_STATE_WAITING_FOR_ACTIVATION
);
573 TEST(SchedulerStateMachineTest
, TestFailedDrawIsRetriedInNextBeginImplFrame
) {
574 SchedulerSettings default_scheduler_settings
;
575 StateMachine
state(default_scheduler_settings
);
577 state
.UpdateState(state
.NextAction());
578 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
579 state
.SetVisible(true);
580 state
.SetCanDraw(true);
583 state
.SetNeedsRedraw(true);
584 EXPECT_TRUE(state
.BeginFrameNeeded());
585 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
586 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
587 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
588 state
.OnBeginImplFrameDeadline();
589 EXPECT_TRUE(state
.RedrawPending());
590 EXPECT_ACTION_UPDATE_STATE(
591 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
593 // Failing the draw for animation checkerboards makes us require a commit.
594 state
.DidDrawIfPossibleCompleted(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS
);
595 EXPECT_ACTION_UPDATE_STATE(
596 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
597 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
598 EXPECT_TRUE(state
.RedrawPending());
600 // We should not be trying to draw again now, but we have a commit pending.
601 EXPECT_TRUE(state
.BeginFrameNeeded());
602 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
603 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
604 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
606 // We should try to draw again at the end of the next BeginImplFrame on
608 state
.OnBeginImplFrameDeadline();
609 EXPECT_ACTION_UPDATE_STATE(
610 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
611 state
.DidSwapBuffers();
612 state
.DidSwapBuffersComplete();
613 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
616 TEST(SchedulerStateMachineTest
, TestDoestDrawTwiceInSameFrame
) {
617 SchedulerSettings default_scheduler_settings
;
618 StateMachine
state(default_scheduler_settings
);
620 state
.UpdateState(state
.NextAction());
621 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
622 state
.SetVisible(true);
623 state
.SetCanDraw(true);
624 state
.SetNeedsRedraw(true);
626 // Draw the first frame.
627 EXPECT_TRUE(state
.BeginFrameNeeded());
628 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
629 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
630 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
632 state
.OnBeginImplFrameDeadline();
633 EXPECT_ACTION_UPDATE_STATE(
634 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
635 state
.DidSwapBuffers();
636 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
637 state
.DidSwapBuffersComplete();
638 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
640 // Before the next BeginImplFrame, set needs redraw again.
641 // This should not redraw until the next BeginImplFrame.
642 state
.SetNeedsRedraw(true);
643 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
645 // Move to another frame. This should now draw.
646 EXPECT_TRUE(state
.BeginFrameNeeded());
647 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
649 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
650 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
652 state
.OnBeginImplFrameDeadline();
653 EXPECT_ACTION_UPDATE_STATE(
654 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
655 state
.DidSwapBuffers();
656 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
657 state
.DidSwapBuffersComplete();
658 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
660 // We just swapped, so we should proactively request another BeginImplFrame.
661 EXPECT_TRUE(state
.BeginFrameNeeded());
664 TEST(SchedulerStateMachineTest
, TestNextActionDrawsOnBeginImplFrame
) {
665 SchedulerSettings default_scheduler_settings
;
667 // When not in BeginImplFrame deadline, or in BeginImplFrame deadline
668 // but not visible, don't draw.
669 size_t num_commit_states
=
670 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
671 size_t num_begin_impl_frame_states
=
672 sizeof(all_begin_impl_frame_states
) /
673 sizeof(SchedulerStateMachine::BeginImplFrameState
);
674 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
675 for (size_t j
= 0; j
< num_begin_impl_frame_states
; ++j
) {
676 StateMachine
state(default_scheduler_settings
);
678 state
.UpdateState(state
.NextAction());
679 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
680 state
.SetCommitState(all_commit_states
[i
]);
681 state
.SetBeginImplFrameState(all_begin_impl_frame_states
[j
]);
683 (all_begin_impl_frame_states
[j
] !=
684 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
685 state
.SetVisible(visible
);
687 // Case 1: needs_commit=false
688 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
691 // Case 2: needs_commit=true
692 state
.SetNeedsCommit();
693 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
699 // When in BeginImplFrame deadline we should always draw for SetNeedsRedraw
700 // except if we're ready to commit, in which case we expect a commit first.
701 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
702 StateMachine
state(default_scheduler_settings
);
704 state
.UpdateState(state
.NextAction());
705 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
706 state
.SetCanDraw(true);
707 state
.SetCommitState(all_commit_states
[i
]);
708 state
.SetBeginImplFrameState(
709 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
711 state
.SetNeedsRedraw(true);
712 state
.SetVisible(true);
714 SchedulerStateMachine::Action expected_action
;
715 if (all_commit_states
[i
] ==
716 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
) {
717 expected_action
= SchedulerStateMachine::ACTION_COMMIT
;
719 expected_action
= SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
;
720 EXPECT_EQ(state
.NextAction(), SchedulerStateMachine::ACTION_ANIMATE
)
722 state
.UpdateState(state
.NextAction());
725 // Case 1: needs_commit=false.
726 EXPECT_EQ(state
.NextAction(), expected_action
) << *state
.AsValue();
728 // Case 2: needs_commit=true.
729 state
.SetNeedsCommit();
730 EXPECT_EQ(state
.NextAction(), expected_action
) << *state
.AsValue();
734 TEST(SchedulerStateMachineTest
, TestNoCommitStatesRedrawWhenInvisible
) {
735 SchedulerSettings default_scheduler_settings
;
737 size_t num_commit_states
=
738 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
739 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
740 // There shouldn't be any drawing regardless of BeginImplFrame.
741 for (size_t j
= 0; j
< 2; ++j
) {
742 StateMachine
state(default_scheduler_settings
);
744 state
.UpdateState(state
.NextAction());
745 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
746 state
.SetCommitState(all_commit_states
[i
]);
747 state
.SetVisible(false);
748 state
.SetNeedsRedraw(true);
750 state
.SetBeginImplFrameState(
751 SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
);
754 // Case 1: needs_commit=false.
755 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
758 // Case 2: needs_commit=true.
759 state
.SetNeedsCommit();
760 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
767 TEST(SchedulerStateMachineTest
, TestCanRedraw_StopsDraw
) {
768 SchedulerSettings default_scheduler_settings
;
770 size_t num_commit_states
=
771 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
772 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
773 // There shouldn't be any drawing regardless of BeginImplFrame.
774 for (size_t j
= 0; j
< 2; ++j
) {
775 StateMachine
state(default_scheduler_settings
);
777 state
.UpdateState(state
.NextAction());
778 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
779 state
.SetCommitState(all_commit_states
[i
]);
780 state
.SetVisible(false);
781 state
.SetNeedsRedraw(true);
783 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
785 state
.SetCanDraw(false);
786 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
792 TEST(SchedulerStateMachineTest
,
793 TestCanRedrawWithWaitingForFirstDrawMakesProgress
) {
794 SchedulerSettings default_scheduler_settings
;
795 StateMachine
state(default_scheduler_settings
);
797 state
.UpdateState(state
.NextAction());
798 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
800 state
.SetActiveTreeNeedsFirstDraw(true);
801 state
.SetNeedsCommit();
802 state
.SetNeedsRedraw(true);
803 state
.SetVisible(true);
804 state
.SetCanDraw(false);
805 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
806 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
807 EXPECT_ACTION_UPDATE_STATE(
808 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
809 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
810 state
.NotifyBeginMainFrameStarted();
811 state
.NotifyReadyToCommit();
812 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
813 state
.OnBeginImplFrameDeadline();
814 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
815 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
818 void TestSetNeedsCommitIsNotLost(bool main_frame_before_draw_enabled
) {
819 SchedulerSettings scheduler_settings
;
820 scheduler_settings
.main_frame_before_draw_enabled
=
821 main_frame_before_draw_enabled
;
822 StateMachine
state(scheduler_settings
);
824 state
.UpdateState(state
.NextAction());
825 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
826 state
.SetNeedsCommit();
827 state
.SetVisible(true);
828 state
.SetCanDraw(true);
830 EXPECT_TRUE(state
.BeginFrameNeeded());
833 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
834 EXPECT_ACTION_UPDATE_STATE(
835 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
836 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
837 state
.CommitState());
839 // Now, while the frame is in progress, set another commit.
840 state
.SetNeedsCommit();
841 EXPECT_TRUE(state
.NeedsCommit());
843 // Let the frame finish.
844 state
.NotifyBeginMainFrameStarted();
845 state
.NotifyReadyToCommit();
846 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
847 state
.CommitState());
849 // Expect to commit regardless of BeginImplFrame state.
850 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
851 state
.begin_impl_frame_state());
852 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
854 state
.OnBeginImplFrameDeadlinePending();
855 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
856 state
.begin_impl_frame_state());
857 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
859 state
.OnBeginImplFrameDeadline();
860 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
,
861 state
.begin_impl_frame_state());
862 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
864 state
.OnBeginImplFrameIdle();
865 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
866 state
.begin_impl_frame_state());
867 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
869 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
870 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
871 state
.begin_impl_frame_state());
872 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
874 // Finish the commit, then make sure we start the next commit immediately
875 // and draw on the next BeginImplFrame.
876 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
877 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
878 if (main_frame_before_draw_enabled
) {
879 EXPECT_ACTION_UPDATE_STATE(
880 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
882 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
884 state
.OnBeginImplFrameDeadline();
886 EXPECT_TRUE(state
.active_tree_needs_first_draw());
887 EXPECT_ACTION_UPDATE_STATE(
888 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
889 state
.DidSwapBuffers();
890 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
891 state
.DidSwapBuffersComplete();
892 if (!main_frame_before_draw_enabled
) {
893 EXPECT_ACTION_UPDATE_STATE(
894 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
896 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
899 TEST(SchedulerStateMachineTest
, TestSetNeedsCommitIsNotLost
) {
900 bool main_frame_before_draw_enabled
= false;
901 TestSetNeedsCommitIsNotLost(main_frame_before_draw_enabled
);
904 TEST(SchedulerStateMachineTest
, TestSetNeedsCommitIsNotLost_CommitBeforeDraw
) {
905 bool main_frame_before_draw_enabled
= true;
906 TestSetNeedsCommitIsNotLost(main_frame_before_draw_enabled
);
909 TEST(SchedulerStateMachineTest
, TestFullCycle
) {
910 SchedulerSettings default_scheduler_settings
;
911 StateMachine
state(default_scheduler_settings
);
913 state
.UpdateState(state
.NextAction());
914 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
915 state
.SetVisible(true);
916 state
.SetCanDraw(true);
918 // Start clean and set commit.
919 state
.SetNeedsCommit();
922 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
923 EXPECT_ACTION_UPDATE_STATE(
924 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
925 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
926 state
.CommitState());
927 EXPECT_FALSE(state
.NeedsCommit());
928 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
930 // Tell the scheduler the frame finished.
931 state
.NotifyBeginMainFrameStarted();
932 state
.NotifyReadyToCommit();
933 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
934 state
.CommitState());
937 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
938 EXPECT_TRUE(state
.active_tree_needs_first_draw());
939 EXPECT_TRUE(state
.needs_redraw());
941 // Expect to do nothing until BeginImplFrame deadline
942 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
944 // At BeginImplFrame deadline, draw.
945 state
.OnBeginImplFrameDeadline();
946 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
947 EXPECT_ACTION_UPDATE_STATE(
948 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
949 state
.DidSwapBuffers();
950 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
951 state
.DidSwapBuffersComplete();
953 // Should be synchronized, no draw needed, no action needed.
954 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
955 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
956 EXPECT_FALSE(state
.needs_redraw());
959 TEST(SchedulerStateMachineTest
, TestFullCycleWithCommitRequestInbetween
) {
960 SchedulerSettings default_scheduler_settings
;
961 StateMachine
state(default_scheduler_settings
);
963 state
.UpdateState(state
.NextAction());
964 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
965 state
.SetVisible(true);
966 state
.SetCanDraw(true);
968 // Start clean and set commit.
969 state
.SetNeedsCommit();
972 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
973 EXPECT_ACTION_UPDATE_STATE(
974 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
975 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
976 state
.CommitState());
977 EXPECT_FALSE(state
.NeedsCommit());
978 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
980 // Request another commit while the commit is in flight.
981 state
.SetNeedsCommit();
982 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
984 // Tell the scheduler the frame finished.
985 state
.NotifyBeginMainFrameStarted();
986 state
.NotifyReadyToCommit();
987 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
988 state
.CommitState());
991 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
992 EXPECT_TRUE(state
.active_tree_needs_first_draw());
993 EXPECT_TRUE(state
.needs_redraw());
995 // Expect to do nothing until BeginImplFrame deadline.
996 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
998 // At BeginImplFrame deadline, draw.
999 state
.OnBeginImplFrameDeadline();
1000 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1001 EXPECT_ACTION_UPDATE_STATE(
1002 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1003 state
.DidSwapBuffers();
1004 state
.DidDrawIfPossibleCompleted(DRAW_SUCCESS
);
1005 state
.DidSwapBuffersComplete();
1007 // Should be synchronized, no draw needed, no action needed.
1008 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1009 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1010 EXPECT_FALSE(state
.needs_redraw());
1012 // Next BeginImplFrame should initiate second commit.
1013 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1014 EXPECT_ACTION_UPDATE_STATE(
1015 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1018 TEST(SchedulerStateMachineTest
, TestRequestCommitInvisible
) {
1019 SchedulerSettings default_scheduler_settings
;
1020 StateMachine
state(default_scheduler_settings
);
1021 state
.SetCanStart();
1022 state
.UpdateState(state
.NextAction());
1023 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1024 state
.SetNeedsCommit();
1025 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1028 TEST(SchedulerStateMachineTest
, TestGoesInvisibleBeforeFinishCommit
) {
1029 SchedulerSettings default_scheduler_settings
;
1030 StateMachine
state(default_scheduler_settings
);
1031 state
.SetCanStart();
1032 state
.UpdateState(state
.NextAction());
1033 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1034 state
.SetVisible(true);
1035 state
.SetCanDraw(true);
1037 // Start clean and set commit.
1038 state
.SetNeedsCommit();
1040 // Begin the frame while visible.
1041 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1042 EXPECT_ACTION_UPDATE_STATE(
1043 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1044 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1045 state
.CommitState());
1046 EXPECT_FALSE(state
.NeedsCommit());
1047 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1049 // Become invisible and abort BeginMainFrame.
1050 state
.SetVisible(false);
1051 state
.BeginMainFrameAborted(false);
1053 // We should now be back in the idle state as if we never started the frame.
1054 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1055 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1057 // We shouldn't do anything on the BeginImplFrame deadline.
1058 state
.OnBeginImplFrameDeadline();
1059 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1061 // Become visible again.
1062 state
.SetVisible(true);
1064 // Although we have aborted on this frame and haven't cancelled the commit
1065 // (i.e. need another), don't send another BeginMainFrame yet.
1066 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1067 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1068 EXPECT_TRUE(state
.NeedsCommit());
1070 // Start a new frame.
1071 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1072 EXPECT_ACTION_UPDATE_STATE(
1073 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1075 // We should be starting the commit now.
1076 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1077 state
.CommitState());
1078 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1081 TEST(SchedulerStateMachineTest
, AbortBeginMainFrameAndCancelCommit
) {
1082 SchedulerSettings default_scheduler_settings
;
1083 StateMachine
state(default_scheduler_settings
);
1084 state
.SetCanStart();
1085 state
.UpdateState(state
.NextAction());
1086 state
.DidCreateAndInitializeOutputSurface();
1087 state
.SetVisible(true);
1088 state
.SetCanDraw(true);
1090 // Get into a begin frame / commit state.
1091 state
.SetNeedsCommit();
1093 EXPECT_ACTION_UPDATE_STATE(
1094 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1095 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1096 state
.CommitState());
1097 EXPECT_FALSE(state
.NeedsCommit());
1098 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1100 // Abort the commit, cancelling future commits.
1101 state
.BeginMainFrameAborted(true);
1103 // Verify that another commit doesn't start on the same frame.
1104 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1105 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1106 EXPECT_FALSE(state
.NeedsCommit());
1108 // Start a new frame; draw because this is the first frame since output
1110 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1111 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1112 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1113 state
.OnBeginImplFrameDeadline();
1114 EXPECT_ACTION_UPDATE_STATE(
1115 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1116 state
.DidSwapBuffers();
1117 state
.DidSwapBuffersComplete();
1119 // Verify another commit doesn't start on another frame either.
1120 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1121 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1122 EXPECT_FALSE(state
.NeedsCommit());
1124 // Verify another commit can start if requested, though.
1125 state
.SetNeedsCommit();
1126 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1127 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
,
1128 state
.NextAction());
1131 TEST(SchedulerStateMachineTest
,
1132 AbortBeginMainFrameAndCancelCommitWhenInvisible
) {
1133 SchedulerSettings default_scheduler_settings
;
1134 StateMachine
state(default_scheduler_settings
);
1135 state
.SetCanStart();
1136 state
.UpdateState(state
.NextAction());
1137 state
.DidCreateAndInitializeOutputSurface();
1138 state
.SetVisible(true);
1139 state
.SetCanDraw(true);
1141 // Get into a begin frame / commit state.
1142 state
.SetNeedsCommit();
1144 EXPECT_ACTION_UPDATE_STATE(
1145 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1146 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1147 state
.CommitState());
1148 EXPECT_FALSE(state
.NeedsCommit());
1149 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1151 // Become invisible and abort BeginMainFrame.
1152 state
.SetVisible(false);
1153 state
.BeginMainFrameAborted(true);
1155 // Verify that another commit doesn't start on the same frame.
1156 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1157 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1158 EXPECT_FALSE(state
.NeedsCommit());
1160 // Become visible and start a new frame.
1161 state
.SetVisible(true);
1162 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1163 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1164 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1166 // Draw because this is the first frame since output surface init'd.
1167 state
.OnBeginImplFrameDeadline();
1168 EXPECT_ACTION_UPDATE_STATE(
1169 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1170 state
.DidSwapBuffers();
1171 state
.DidSwapBuffersComplete();
1173 // Verify another commit doesn't start on another frame either.
1174 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1175 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1176 EXPECT_FALSE(state
.NeedsCommit());
1178 // Verify another commit can start if requested, though.
1179 state
.SetNeedsCommit();
1180 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1181 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
,
1182 state
.NextAction());
1185 TEST(SchedulerStateMachineTest
,
1186 AbortBeginMainFrameAndRequestCommitWhenInvisible
) {
1187 SchedulerSettings default_scheduler_settings
;
1188 StateMachine
state(default_scheduler_settings
);
1189 state
.SetCanStart();
1190 state
.UpdateState(state
.NextAction());
1191 state
.DidCreateAndInitializeOutputSurface();
1192 state
.SetVisible(true);
1193 state
.SetCanDraw(true);
1195 // Get into a begin frame / commit state.
1196 state
.SetNeedsCommit();
1198 EXPECT_ACTION_UPDATE_STATE(
1199 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1200 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1201 state
.CommitState());
1202 EXPECT_FALSE(state
.NeedsCommit());
1203 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1205 // Become invisible and abort BeginMainFrame.
1206 state
.SetVisible(false);
1207 state
.BeginMainFrameAborted(true);
1209 // Verify that another commit doesn't start on the same frame.
1210 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1211 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1212 EXPECT_FALSE(state
.NeedsCommit());
1214 // Asking for a commit while not visible won't make it happen.
1215 state
.SetNeedsCommit();
1216 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1217 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1218 EXPECT_TRUE(state
.NeedsCommit());
1220 // Become visible but nothing happens until the next frame.
1221 state
.SetVisible(true);
1222 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1223 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1224 EXPECT_TRUE(state
.NeedsCommit());
1226 // We should get that commit when we begin the next frame.
1227 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1228 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1229 EXPECT_ACTION_UPDATE_STATE(
1230 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1233 TEST(SchedulerStateMachineTest
,
1234 AbortBeginMainFrameAndRequestCommitAndBeginImplFrameWhenInvisible
) {
1235 SchedulerSettings default_scheduler_settings
;
1236 StateMachine
state(default_scheduler_settings
);
1237 state
.SetCanStart();
1238 state
.UpdateState(state
.NextAction());
1239 state
.DidCreateAndInitializeOutputSurface();
1240 state
.SetVisible(true);
1241 state
.SetCanDraw(true);
1243 // Get into a begin frame / commit state.
1244 state
.SetNeedsCommit();
1246 EXPECT_ACTION_UPDATE_STATE(
1247 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1248 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1249 state
.CommitState());
1250 EXPECT_FALSE(state
.NeedsCommit());
1251 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1253 // Become invisible and abort BeginMainFrame.
1254 state
.SetVisible(false);
1255 state
.BeginMainFrameAborted(true);
1257 // Asking for a commit while not visible won't make it happen.
1258 state
.SetNeedsCommit();
1259 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1260 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1261 EXPECT_TRUE(state
.NeedsCommit());
1263 // Begin a frame when not visible, the scheduler animates but does not commit.
1264 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1265 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1266 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1267 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1268 EXPECT_TRUE(state
.NeedsCommit());
1270 // Become visible and the requested commit happens immediately.
1271 state
.SetVisible(true);
1272 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1273 EXPECT_ACTION_UPDATE_STATE(
1274 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1277 TEST(SchedulerStateMachineTest
, TestFirstContextCreation
) {
1278 SchedulerSettings default_scheduler_settings
;
1279 StateMachine
state(default_scheduler_settings
);
1280 state
.SetCanStart();
1281 state
.SetVisible(true);
1282 state
.SetCanDraw(true);
1284 EXPECT_ACTION_UPDATE_STATE(
1285 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1286 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1287 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1289 // Check that the first init does not SetNeedsCommit.
1290 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1291 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1292 state
.OnBeginImplFrameDeadline();
1293 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1295 // Check that a needs commit initiates a BeginMainFrame.
1296 state
.SetNeedsCommit();
1297 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1298 EXPECT_ACTION_UPDATE_STATE(
1299 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1302 TEST(SchedulerStateMachineTest
, TestContextLostWhenCompletelyIdle
) {
1303 SchedulerSettings default_scheduler_settings
;
1304 StateMachine
state(default_scheduler_settings
);
1305 state
.SetCanStart();
1306 state
.UpdateState(state
.NextAction());
1307 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1309 state
.SetVisible(true);
1310 state
.SetCanDraw(true);
1312 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1313 state
.NextAction());
1314 state
.DidLoseOutputSurface();
1316 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1317 state
.NextAction());
1318 state
.UpdateState(state
.NextAction());
1320 // Once context recreation begins, nothing should happen.
1321 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1323 // Recreate the context.
1324 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1326 // When the context is recreated, we should begin a commit.
1327 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1328 EXPECT_ACTION_UPDATE_STATE(
1329 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1332 TEST(SchedulerStateMachineTest
,
1333 TestContextLostWhenIdleAndCommitRequestedWhileRecreating
) {
1334 SchedulerSettings default_scheduler_settings
;
1335 StateMachine
state(default_scheduler_settings
);
1336 state
.SetCanStart();
1337 state
.UpdateState(state
.NextAction());
1338 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1339 state
.SetVisible(true);
1340 state
.SetCanDraw(true);
1342 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1343 state
.NextAction());
1344 state
.DidLoseOutputSurface();
1346 EXPECT_ACTION_UPDATE_STATE(
1347 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1348 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1350 // Once context recreation begins, nothing should happen.
1351 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1352 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1353 state
.OnBeginImplFrameDeadline();
1354 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1356 // While context is recreating, commits shouldn't begin.
1357 state
.SetNeedsCommit();
1358 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1359 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1360 state
.OnBeginImplFrameDeadline();
1361 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1363 // Recreate the context
1364 state
.DidCreateAndInitializeOutputSurface();
1365 EXPECT_FALSE(state
.RedrawPending());
1367 // When the context is recreated, we should begin a commit
1368 EXPECT_ACTION_UPDATE_STATE(
1369 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1370 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1371 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
,
1372 state
.CommitState());
1374 state
.NotifyBeginMainFrameStarted();
1375 state
.NotifyReadyToCommit();
1376 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1377 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1378 // Finishing the first commit after initializing an output surface should
1379 // automatically cause a redraw.
1380 EXPECT_TRUE(state
.RedrawPending());
1382 // Once the context is recreated, whether we draw should be based on
1384 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1385 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1386 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1387 state
.OnBeginImplFrameDeadline();
1388 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
1389 state
.NextAction());
1390 state
.SetCanDraw(false);
1391 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
,
1392 state
.NextAction());
1393 state
.SetCanDraw(true);
1394 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
,
1395 state
.NextAction());
1398 TEST(SchedulerStateMachineTest
, TestContextLostWhileCommitInProgress
) {
1399 SchedulerSettings scheduler_settings
;
1400 StateMachine
state(scheduler_settings
);
1401 state
.SetCanStart();
1402 state
.UpdateState(state
.NextAction());
1403 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1404 state
.SetVisible(true);
1405 state
.SetCanDraw(true);
1407 // Get a commit in flight.
1408 state
.SetNeedsCommit();
1410 // Set damage and expect a draw.
1411 state
.SetNeedsRedraw(true);
1412 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1413 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1414 EXPECT_ACTION_UPDATE_STATE(
1415 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1416 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1417 state
.OnBeginImplFrameDeadline();
1418 EXPECT_ACTION_UPDATE_STATE(
1419 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1420 state
.DidSwapBuffers();
1421 state
.DidSwapBuffersComplete();
1422 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1424 // Cause a lost context while the BeginMainFrame is in flight.
1425 state
.DidLoseOutputSurface();
1427 // Ask for another draw. Expect nothing happens.
1428 state
.SetNeedsRedraw(true);
1429 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1431 // Finish the frame, and commit.
1432 state
.NotifyBeginMainFrameStarted();
1433 state
.NotifyReadyToCommit();
1434 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1436 // We will abort the draw when the output surface is lost if we are
1437 // waiting for the first draw to unblock the main thread.
1438 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1439 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1441 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1442 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
1443 state
.begin_impl_frame_state());
1444 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1445 state
.NextAction());
1447 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1448 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
1449 state
.begin_impl_frame_state());
1450 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1452 state
.OnBeginImplFrameDeadlinePending();
1453 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
1454 state
.begin_impl_frame_state());
1455 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1457 state
.OnBeginImplFrameDeadline();
1458 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
,
1459 state
.begin_impl_frame_state());
1460 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1463 TEST(SchedulerStateMachineTest
,
1464 TestContextLostWhileCommitInProgressAndAnotherCommitRequested
) {
1465 SchedulerSettings scheduler_settings
;
1466 StateMachine
state(scheduler_settings
);
1467 state
.SetCanStart();
1468 state
.UpdateState(state
.NextAction());
1469 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1470 state
.SetVisible(true);
1471 state
.SetCanDraw(true);
1473 // Get a commit in flight.
1474 state
.SetNeedsCommit();
1475 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1477 // Set damage and expect a draw.
1478 state
.SetNeedsRedraw(true);
1479 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1480 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1481 EXPECT_ACTION_UPDATE_STATE(
1482 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1483 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1484 state
.OnBeginImplFrameDeadline();
1485 EXPECT_ACTION_UPDATE_STATE(
1486 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1487 state
.DidSwapBuffers();
1488 state
.DidSwapBuffersComplete();
1489 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1491 // Cause a lost context while the BeginMainFrame is in flight.
1492 state
.DidLoseOutputSurface();
1494 // Ask for another draw and also set needs commit. Expect nothing happens.
1495 state
.SetNeedsRedraw(true);
1496 state
.SetNeedsCommit();
1497 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1499 // Finish the frame, and commit.
1500 state
.NotifyBeginMainFrameStarted();
1501 state
.NotifyReadyToCommit();
1502 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1503 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1505 // Because the output surface is missing, we expect the draw to abort.
1506 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1508 // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE
1509 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE
,
1510 state
.begin_impl_frame_state());
1511 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1512 state
.NextAction());
1514 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1515 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_BEGIN_FRAME_STARTING
,
1516 state
.begin_impl_frame_state());
1517 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1519 state
.OnBeginImplFrameDeadlinePending();
1520 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME
,
1521 state
.begin_impl_frame_state());
1522 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1524 state
.OnBeginImplFrameDeadline();
1525 EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE
,
1526 state
.begin_impl_frame_state());
1527 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1529 state
.OnBeginImplFrameIdle();
1530 EXPECT_ACTION_UPDATE_STATE(
1531 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1533 // After we get a new output surface, the commit flow should start.
1534 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1535 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1536 EXPECT_ACTION_UPDATE_STATE(
1537 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1538 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1539 state
.NotifyBeginMainFrameStarted();
1540 state
.NotifyReadyToCommit();
1541 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1542 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1543 state
.OnBeginImplFrameDeadline();
1544 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1545 EXPECT_ACTION_UPDATE_STATE(
1546 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1547 state
.DidSwapBuffers();
1548 state
.DidSwapBuffersComplete();
1549 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1552 TEST(SchedulerStateMachineTest
, DontDrawBeforeCommitAfterLostOutputSurface
) {
1553 SchedulerSettings default_scheduler_settings
;
1554 StateMachine
state(default_scheduler_settings
);
1555 state
.SetCanStart();
1556 state
.UpdateState(state
.NextAction());
1557 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1558 state
.SetVisible(true);
1559 state
.SetCanDraw(true);
1561 state
.SetNeedsRedraw(true);
1563 // Cause a lost output surface, and restore it.
1564 state
.DidLoseOutputSurface();
1565 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1566 state
.NextAction());
1567 state
.UpdateState(state
.NextAction());
1568 state
.DidCreateAndInitializeOutputSurface();
1570 EXPECT_FALSE(state
.RedrawPending());
1571 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1572 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
,
1573 state
.NextAction());
1576 TEST(SchedulerStateMachineTest
,
1577 TestPendingActivationsShouldBeForcedAfterLostOutputSurface
) {
1578 SchedulerSettings settings
;
1579 settings
.impl_side_painting
= true;
1580 StateMachine
state(settings
);
1581 state
.SetCanStart();
1582 state
.UpdateState(state
.NextAction());
1583 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1584 state
.SetVisible(true);
1585 state
.SetCanDraw(true);
1587 state
.SetCommitState(
1588 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1590 // Cause a lost context.
1591 state
.DidLoseOutputSurface();
1593 state
.NotifyBeginMainFrameStarted();
1594 state
.NotifyReadyToCommit();
1595 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1597 EXPECT_TRUE(state
.PendingActivationsShouldBeForced());
1598 EXPECT_ACTION_UPDATE_STATE(
1599 SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE
);
1601 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1602 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1605 TEST(SchedulerStateMachineTest
, TestNoBeginMainFrameWhenInvisible
) {
1606 SchedulerSettings default_scheduler_settings
;
1607 StateMachine
state(default_scheduler_settings
);
1608 state
.SetCanStart();
1609 state
.UpdateState(state
.NextAction());
1610 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1611 state
.SetVisible(false);
1612 state
.SetNeedsCommit();
1613 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1616 TEST(SchedulerStateMachineTest
, TestFinishCommitWhenCommitInProgress
) {
1617 SchedulerSettings default_scheduler_settings
;
1618 StateMachine
state(default_scheduler_settings
);
1619 state
.SetCanStart();
1620 state
.UpdateState(state
.NextAction());
1621 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1622 state
.SetVisible(false);
1623 state
.SetCommitState(
1624 SchedulerStateMachine::COMMIT_STATE_BEGIN_MAIN_FRAME_SENT
);
1625 state
.SetNeedsCommit();
1627 state
.NotifyBeginMainFrameStarted();
1628 state
.NotifyReadyToCommit();
1629 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
1630 state
.UpdateState(state
.NextAction());
1632 EXPECT_TRUE(state
.active_tree_needs_first_draw());
1633 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
);
1636 TEST(SchedulerStateMachineTest
, TestInitialActionsWhenContextLost
) {
1637 SchedulerSettings default_scheduler_settings
;
1638 StateMachine
state(default_scheduler_settings
);
1639 state
.SetCanStart();
1640 state
.UpdateState(state
.NextAction());
1641 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1642 state
.SetVisible(true);
1643 state
.SetCanDraw(true);
1644 state
.SetNeedsCommit();
1645 state
.DidLoseOutputSurface();
1647 // When we are visible, we normally want to begin output surface creation
1648 // as soon as possible.
1649 EXPECT_ACTION_UPDATE_STATE(
1650 SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
);
1652 state
.DidCreateAndInitializeOutputSurface();
1653 EXPECT_EQ(state
.output_surface_state(),
1654 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT
);
1656 // We should not send a BeginMainFrame when we are invisible, even if we've
1657 // lost the output surface and are trying to get the first commit, since the
1658 // main thread will just abort anyway.
1659 state
.SetVisible(false);
1660 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction())
1661 << *state
.AsValue();
1664 TEST(SchedulerStateMachineTest
, ReportIfNotDrawing
) {
1665 SchedulerSettings default_scheduler_settings
;
1666 StateMachine
state(default_scheduler_settings
);
1667 state
.SetCanStart();
1668 state
.UpdateState(state
.NextAction());
1669 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1671 state
.SetCanDraw(true);
1672 state
.SetVisible(true);
1673 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1675 state
.SetCanDraw(false);
1676 state
.SetVisible(true);
1677 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1679 state
.SetCanDraw(true);
1680 state
.SetVisible(false);
1681 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1683 state
.SetCanDraw(false);
1684 state
.SetVisible(false);
1685 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1687 state
.SetCanDraw(true);
1688 state
.SetVisible(true);
1689 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1692 TEST(SchedulerStateMachineTest
, TestTriggerDeadlineEarlyAfterAbortedCommit
) {
1693 SchedulerSettings settings
;
1694 settings
.impl_side_painting
= true;
1695 StateMachine
state(settings
);
1696 state
.SetCanStart();
1697 state
.UpdateState(state
.NextAction());
1698 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1699 state
.SetVisible(true);
1700 state
.SetCanDraw(true);
1702 // This test mirrors what happens during the first frame of a scroll gesture.
1703 // First we get the input event and a BeginFrame.
1704 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1706 // As a response the compositor requests a redraw and a commit to tell the
1707 // main thread about the new scroll offset.
1708 state
.SetNeedsRedraw(true);
1709 state
.SetNeedsCommit();
1711 // We should start the commit normally.
1712 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1713 EXPECT_ACTION_UPDATE_STATE(
1714 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1715 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1717 // Since only the scroll offset changed, the main thread will abort the
1719 state
.BeginMainFrameAborted(true);
1721 // Since the commit was aborted, we should draw right away instead of waiting
1722 // for the deadline.
1723 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1726 void FinishPreviousCommitAndDrawWithoutExitingDeadline(
1727 StateMachine
* state_ptr
) {
1728 // Gross, but allows us to use macros below.
1729 StateMachine
& state
= *state_ptr
;
1731 state
.NotifyBeginMainFrameStarted();
1732 state
.NotifyReadyToCommit();
1733 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT
);
1734 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1735 state
.NotifyReadyToActivate();
1736 EXPECT_ACTION_UPDATE_STATE(
1737 SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE
);
1738 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1740 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1741 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1742 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1744 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1745 state
.OnBeginImplFrameDeadline();
1746 EXPECT_ACTION_UPDATE_STATE(
1747 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1748 state
.DidSwapBuffers();
1751 TEST(SchedulerStateMachineTest
, TestSmoothnessTakesPriority
) {
1752 SchedulerSettings settings
;
1753 settings
.impl_side_painting
= true;
1754 StateMachine
state(settings
);
1755 state
.SetCanStart();
1756 state
.UpdateState(state
.NextAction());
1757 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1758 state
.SetVisible(true);
1759 state
.SetCanDraw(true);
1761 // This test ensures that impl-draws are prioritized over main thread updates
1762 // in prefer smoothness mode.
1763 state
.SetNeedsRedraw(true);
1764 state
.SetNeedsCommit();
1765 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1766 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1767 EXPECT_ACTION_UPDATE_STATE(
1768 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1769 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1771 // Verify the deadline is not triggered early until we enter
1772 // prefer smoothness mode.
1773 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1774 state
.SetSmoothnessTakesPriority(true);
1775 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1777 // Trigger the deadline.
1778 state
.OnBeginImplFrameDeadline();
1779 EXPECT_ACTION_UPDATE_STATE(
1780 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1781 state
.DidSwapBuffers();
1782 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1783 state
.DidSwapBuffersComplete();
1785 // Request a new commit and finish the previous one.
1786 state
.SetNeedsCommit();
1787 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1788 EXPECT_ACTION_UPDATE_STATE(
1789 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1790 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1791 state
.DidSwapBuffersComplete();
1792 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1794 // Finish the previous commit and draw it.
1795 FinishPreviousCommitAndDrawWithoutExitingDeadline(&state
);
1796 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1798 // Verify we do not send another BeginMainFrame if was are swap throttled
1799 // and did not just swap.
1800 state
.SetNeedsCommit();
1801 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1802 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1803 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1804 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1805 state
.OnBeginImplFrameDeadline();
1806 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1809 TEST(SchedulerStateMachineTest
, TestTriggerDeadlineEarlyOnLostOutputSurface
) {
1810 SchedulerSettings default_scheduler_settings
;
1811 StateMachine
state(default_scheduler_settings
);
1812 state
.SetCanStart();
1813 state
.UpdateState(state
.NextAction());
1814 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1815 state
.SetVisible(true);
1816 state
.SetCanDraw(true);
1818 state
.SetNeedsCommit();
1820 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1821 EXPECT_ACTION_UPDATE_STATE(
1822 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1823 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1824 EXPECT_FALSE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1826 state
.DidLoseOutputSurface();
1827 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1828 // The deadline should be triggered immediately when output surface is lost.
1829 EXPECT_TRUE(state
.ShouldTriggerBeginImplFrameDeadlineEarly());
1832 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimate
) {
1833 SchedulerSettings settings
;
1834 settings
.impl_side_painting
= true;
1835 StateMachine
state(settings
);
1836 state
.SetCanStart();
1837 state
.UpdateState(state
.NextAction());
1838 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1839 state
.SetVisible(true);
1840 state
.SetCanDraw(true);
1842 // Test requesting an animation that, when run, causes us to draw.
1843 state
.SetNeedsAnimate();
1844 EXPECT_TRUE(state
.BeginFrameNeeded());
1845 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1847 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1848 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1850 state
.OnBeginImplFrameDeadlinePending();
1851 state
.OnBeginImplFrameDeadline();
1852 EXPECT_ACTION_UPDATE_STATE(
1853 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1856 TEST(SchedulerStateMachineTest
, TestAnimateBeforeCommit
) {
1857 SchedulerSettings settings
;
1858 settings
.impl_side_painting
= true;
1859 StateMachine
state(settings
);
1860 state
.SetCanStart();
1861 state
.UpdateState(state
.NextAction());
1862 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1863 state
.SetVisible(true);
1864 state
.SetCanDraw(true);
1866 // Check that animations are updated before we start a commit.
1867 state
.SetNeedsAnimate();
1868 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1869 state
.SetNeedsCommit();
1870 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1871 EXPECT_TRUE(state
.BeginFrameNeeded());
1873 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1874 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1875 EXPECT_ACTION_UPDATE_STATE(
1876 SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME
);
1878 state
.OnBeginImplFrameDeadlinePending();
1879 state
.OnBeginImplFrameDeadline();
1880 EXPECT_ACTION_UPDATE_STATE(
1881 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);
1884 TEST(SchedulerStateMachineTest
, TestSetNeedsAnimateAfterAnimate
) {
1885 SchedulerSettings settings
;
1886 settings
.impl_side_painting
= true;
1887 StateMachine
state(settings
);
1888 state
.SetCanStart();
1889 state
.UpdateState(state
.NextAction());
1890 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1891 state
.SetVisible(true);
1892 state
.SetCanDraw(true);
1894 // Test requesting an animation after we have already animated during this
1896 state
.SetNeedsRedraw(true);
1897 EXPECT_TRUE(state
.BeginFrameNeeded());
1898 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1900 state
.OnBeginImplFrame(CreateBeginFrameArgsForTesting());
1901 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ANIMATE
);
1903 state
.SetNeedsAnimate();
1904 EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE
);
1906 state
.OnBeginImplFrameDeadline();
1907 EXPECT_ACTION_UPDATE_STATE(
1908 SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE
);