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