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 "testing/gtest/include/gtest/gtest.h"
14 const SchedulerStateMachine::CommitState all_commit_states
[] = {
15 SchedulerStateMachine::COMMIT_STATE_IDLE
,
16 SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
17 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
18 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
21 // Exposes the protected state fields of the SchedulerStateMachine for testing
22 class StateMachine
: public SchedulerStateMachine
{
24 explicit StateMachine(const SchedulerSettings
& scheduler_settings
)
25 : SchedulerStateMachine(scheduler_settings
) {}
27 void CreateAndInitializeOutputSurfaceWithActivatedCommit() {
28 DidCreateAndInitializeOutputSurface();
29 output_surface_state_
= OUTPUT_SURFACE_ACTIVE
;
32 void SetCommitState(CommitState cs
) { commit_state_
= cs
; }
33 CommitState
CommitState() const { return commit_state_
; }
35 OutputSurfaceState
output_surface_state() const {
36 return output_surface_state_
;
39 bool NeedsCommit() const { return needs_commit_
; }
41 void SetNeedsRedraw(bool b
) { needs_redraw_
= b
; }
42 bool NeedsRedraw() const { return needs_redraw_
; }
44 void SetNeedsForcedRedraw(bool b
) { needs_forced_redraw_
= b
; }
45 bool NeedsForcedRedraw() const { return needs_forced_redraw_
; }
47 bool CanDraw() const { return can_draw_
; }
48 bool Visible() const { return visible_
; }
51 TEST(SchedulerStateMachineTest
, TestNextActionBeginsMainFrameIfNeeded
) {
52 SchedulerSettings default_scheduler_settings
;
54 // If no commit needed, do nothing.
56 StateMachine
state(default_scheduler_settings
);
58 state
.UpdateState(state
.NextAction());
59 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
60 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
61 state
.SetNeedsRedraw(false);
62 state
.SetVisible(true);
64 EXPECT_FALSE(state
.BeginFrameNeededToDrawByImplThread());
66 state
.DidLeaveBeginFrame();
67 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
68 EXPECT_FALSE(state
.BeginFrameNeededToDrawByImplThread());
69 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
70 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
73 // If commit requested but can_start is still false, do nothing.
75 StateMachine
state(default_scheduler_settings
);
76 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
77 state
.SetNeedsRedraw(false);
78 state
.SetVisible(true);
80 EXPECT_FALSE(state
.BeginFrameNeededToDrawByImplThread());
82 state
.DidLeaveBeginFrame();
83 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
84 EXPECT_FALSE(state
.BeginFrameNeededToDrawByImplThread());
85 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
86 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
89 // If commit requested, begin a main frame.
91 StateMachine
state(default_scheduler_settings
);
92 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE
);
94 state
.SetNeedsRedraw(false);
95 state
.SetVisible(true);
96 EXPECT_FALSE(state
.BeginFrameNeededToDrawByImplThread());
99 // Begin the frame, make sure needs_commit and commit_state update correctly.
101 StateMachine
state(default_scheduler_settings
);
103 state
.UpdateState(state
.NextAction());
104 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
105 state
.SetVisible(true);
107 SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
);
108 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
109 state
.CommitState());
110 EXPECT_FALSE(state
.NeedsCommit());
111 EXPECT_FALSE(state
.BeginFrameNeededToDrawByImplThread());
115 TEST(SchedulerStateMachineTest
, TestSetForcedRedrawDoesNotSetsNormalRedraw
) {
116 SchedulerSettings default_scheduler_settings
;
117 SchedulerStateMachine
state(default_scheduler_settings
);
118 state
.SetCanDraw(true);
119 state
.SetNeedsForcedRedraw();
120 EXPECT_FALSE(state
.RedrawPending());
121 EXPECT_TRUE(state
.BeginFrameNeededToDrawByImplThread());
124 TEST(SchedulerStateMachineTest
,
125 TestFailedDrawSetsNeedsCommitAndDoesNotDrawAgain
) {
126 SchedulerSettings default_scheduler_settings
;
127 StateMachine
state(default_scheduler_settings
);
129 state
.UpdateState(state
.NextAction());
130 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
131 state
.SetVisible(true);
132 state
.SetCanDraw(true);
133 state
.SetNeedsRedraw(true);
134 EXPECT_TRUE(state
.RedrawPending());
135 EXPECT_TRUE(state
.BeginFrameNeededToDrawByImplThread());
136 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
138 // We're drawing now.
139 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
, state
.NextAction());
140 state
.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
);
141 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
142 EXPECT_FALSE(state
.RedrawPending());
143 EXPECT_FALSE(state
.CommitPending());
145 // Failing the draw makes us require a commit.
146 state
.DidDrawIfPossibleCompleted(false);
147 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
150 SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
);
151 EXPECT_TRUE(state
.RedrawPending());
152 EXPECT_TRUE(state
.CommitPending());
155 TEST(SchedulerStateMachineTest
,
156 TestsetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw
) {
157 SchedulerSettings default_scheduler_settings
;
158 StateMachine
state(default_scheduler_settings
);
160 state
.UpdateState(state
.NextAction());
161 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
163 state
.SetVisible(true);
164 state
.SetCanDraw(true);
165 state
.SetNeedsRedraw(true);
166 EXPECT_TRUE(state
.RedrawPending());
167 EXPECT_TRUE(state
.BeginFrameNeededToDrawByImplThread());
168 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
170 // We're drawing now.
171 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
, state
.NextAction());
172 state
.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
);
173 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
174 EXPECT_FALSE(state
.RedrawPending());
175 EXPECT_FALSE(state
.CommitPending());
177 // While still in the same begin frame callback on the main thread,
178 // set needs redraw again. This should not redraw.
179 state
.SetNeedsRedraw(true);
180 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
182 // Failing the draw makes us require a commit.
183 state
.DidDrawIfPossibleCompleted(false);
184 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
186 EXPECT_TRUE(state
.RedrawPending());
189 TEST(SchedulerStateMachineTest
,
190 TestCommitAfterFailedDrawAllowsDrawInSameFrame
) {
191 SchedulerSettings default_scheduler_settings
;
192 StateMachine
state(default_scheduler_settings
);
194 state
.UpdateState(state
.NextAction());
195 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
196 state
.SetVisible(true);
197 state
.SetCanDraw(true);
200 state
.SetNeedsCommit();
201 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
204 SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
);
205 EXPECT_TRUE(state
.CommitPending());
207 // Then initiate a draw.
208 state
.SetNeedsRedraw(true);
209 EXPECT_TRUE(state
.BeginFrameNeededToDrawByImplThread());
210 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
211 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
, state
.NextAction());
212 EXPECT_TRUE(state
.RedrawPending());
215 state
.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
);
216 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
217 state
.DidDrawIfPossibleCompleted(false);
218 EXPECT_TRUE(state
.RedrawPending());
219 // But the commit is ongoing.
220 EXPECT_TRUE(state
.CommitPending());
222 // Finish the commit.
223 state
.FinishCommit();
224 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
225 state
.UpdateState(SchedulerStateMachine::ACTION_COMMIT
);
226 EXPECT_TRUE(state
.RedrawPending());
228 // And we should be allowed to draw again.
229 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
, state
.NextAction());
232 TEST(SchedulerStateMachineTest
,
233 TestCommitAfterFailedAndSuccessfulDrawDoesNotAllowDrawInSameFrame
) {
234 SchedulerSettings default_scheduler_settings
;
235 StateMachine
state(default_scheduler_settings
);
237 state
.UpdateState(state
.NextAction());
238 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
239 state
.SetVisible(true);
240 state
.SetCanDraw(true);
243 state
.SetNeedsCommit();
244 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
247 SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
);
248 EXPECT_TRUE(state
.CommitPending());
250 // Then initiate a draw.
251 state
.SetNeedsRedraw(true);
252 EXPECT_TRUE(state
.BeginFrameNeededToDrawByImplThread());
253 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
254 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
, state
.NextAction());
255 EXPECT_TRUE(state
.RedrawPending());
258 state
.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
);
259 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
260 state
.DidDrawIfPossibleCompleted(false);
261 EXPECT_TRUE(state
.RedrawPending());
262 // But the commit is ongoing.
263 EXPECT_TRUE(state
.CommitPending());
266 state
.SetNeedsForcedRedraw(true);
267 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED
, state
.NextAction());
269 // Do the forced draw.
270 state
.UpdateState(SchedulerStateMachine::ACTION_DRAW_FORCED
);
271 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
272 EXPECT_FALSE(state
.RedrawPending());
273 // And the commit is still ongoing.
274 EXPECT_TRUE(state
.CommitPending());
276 // Finish the commit.
277 state
.FinishCommit();
278 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
279 state
.UpdateState(SchedulerStateMachine::ACTION_COMMIT
);
280 EXPECT_TRUE(state
.RedrawPending());
282 // And we should not be allowed to draw again in the same frame..
283 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
286 TEST(SchedulerStateMachineTest
,
287 TestFailedDrawsWillEventuallyForceADrawAfterTheNextCommit
) {
288 SchedulerSettings default_scheduler_settings
;
289 StateMachine
state(default_scheduler_settings
);
291 state
.UpdateState(state
.NextAction());
292 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
293 state
.SetVisible(true);
294 state
.SetCanDraw(true);
295 state
.SetMaximumNumberOfFailedDrawsBeforeDrawIsForced(1);
298 state
.SetNeedsCommit();
299 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
302 SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
);
303 EXPECT_TRUE(state
.CommitPending());
305 // Then initiate a draw.
306 state
.SetNeedsRedraw(true);
307 EXPECT_TRUE(state
.BeginFrameNeededToDrawByImplThread());
308 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
309 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
, state
.NextAction());
310 EXPECT_TRUE(state
.RedrawPending());
313 state
.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
);
314 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
315 state
.DidDrawIfPossibleCompleted(false);
316 EXPECT_TRUE(state
.RedrawPending());
317 // But the commit is ongoing.
318 EXPECT_TRUE(state
.CommitPending());
320 // Finish the commit. Note, we should not yet be forcing a draw, but should
321 // continue the commit as usual.
322 state
.FinishCommit();
323 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
324 state
.UpdateState(SchedulerStateMachine::ACTION_COMMIT
);
325 EXPECT_TRUE(state
.RedrawPending());
327 // The redraw should be forced in this case.
328 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED
, state
.NextAction());
331 TEST(SchedulerStateMachineTest
,
332 TestFailedDrawIsRetriedInNextBeginFrameForImplThread
) {
333 SchedulerSettings default_scheduler_settings
;
334 StateMachine
state(default_scheduler_settings
);
336 state
.UpdateState(state
.NextAction());
337 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
338 state
.SetVisible(true);
339 state
.SetCanDraw(true);
342 state
.SetNeedsRedraw(true);
343 EXPECT_TRUE(state
.BeginFrameNeededToDrawByImplThread());
344 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
345 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
, state
.NextAction());
346 EXPECT_TRUE(state
.RedrawPending());
349 state
.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
);
350 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
351 state
.DidDrawIfPossibleCompleted(false);
352 EXPECT_TRUE(state
.RedrawPending());
354 // We should not be trying to draw again now, but we have a commit pending.
355 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
358 state
.DidLeaveBeginFrame();
359 EXPECT_TRUE(state
.BeginFrameNeededToDrawByImplThread());
360 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
362 // We should try to draw again in the next begin frame on the impl thread.
363 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
, state
.NextAction());
366 TEST(SchedulerStateMachineTest
, TestDoestDrawTwiceInSameFrame
) {
367 SchedulerSettings default_scheduler_settings
;
368 StateMachine
state(default_scheduler_settings
);
370 state
.UpdateState(state
.NextAction());
371 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
372 state
.SetVisible(true);
373 state
.SetCanDraw(true);
374 state
.SetNeedsRedraw(true);
375 EXPECT_TRUE(state
.BeginFrameNeededToDrawByImplThread());
376 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
377 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
, state
.NextAction());
378 state
.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
);
380 // While still in the same begin frame for the impl thread, set needs redraw
381 // again. This should not redraw.
382 state
.SetNeedsRedraw(true);
383 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
385 // Move to another frame. This should now draw.
386 state
.DidDrawIfPossibleCompleted(true);
387 state
.DidLeaveBeginFrame();
388 EXPECT_TRUE(state
.BeginFrameNeededToDrawByImplThread());
389 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
391 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
, state
.NextAction());
392 state
.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
);
393 state
.DidDrawIfPossibleCompleted(true);
394 EXPECT_FALSE(state
.BeginFrameNeededToDrawByImplThread());
397 TEST(SchedulerStateMachineTest
, TestNextActionDrawsOnBeginFrame
) {
398 SchedulerSettings default_scheduler_settings
;
400 // When not in BeginFrame, or in BeginFrame but not visible,
402 size_t num_commit_states
=
403 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
404 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
405 for (size_t j
= 0; j
< 2; ++j
) {
406 StateMachine
state(default_scheduler_settings
);
408 state
.UpdateState(state
.NextAction());
409 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
410 state
.SetCommitState(all_commit_states
[i
]);
413 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
414 state
.SetVisible(false);
416 state
.SetVisible(true);
419 // Case 1: needs_commit=false
420 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
,
423 // Case 2: needs_commit=true
424 state
.SetNeedsCommit();
425 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
,
430 // When in BeginFrame, or not in BeginFrame but needs_forced_dedraw
431 // set, should always draw except if you're ready to commit, in which case
433 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
434 for (size_t j
= 0; j
< 2; ++j
) {
435 StateMachine
state(default_scheduler_settings
);
437 state
.UpdateState(state
.NextAction());
438 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
439 state
.SetCanDraw(true);
440 state
.SetCommitState(all_commit_states
[i
]);
441 bool forced_draw
= j
;
443 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
444 state
.SetNeedsRedraw(true);
445 state
.SetVisible(true);
447 state
.SetNeedsForcedRedraw(true);
450 SchedulerStateMachine::Action expected_action
;
451 if (all_commit_states
[i
] !=
452 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
) {
454 forced_draw
? SchedulerStateMachine::ACTION_DRAW_FORCED
455 : SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
;
457 expected_action
= SchedulerStateMachine::ACTION_COMMIT
;
460 // Case 1: needs_commit=false.
461 EXPECT_TRUE(state
.BeginFrameNeededToDrawByImplThread());
462 EXPECT_EQ(expected_action
, state
.NextAction()) << *state
.AsValue();
464 // Case 2: needs_commit=true.
465 state
.SetNeedsCommit();
466 EXPECT_TRUE(state
.BeginFrameNeededToDrawByImplThread());
467 EXPECT_EQ(expected_action
, state
.NextAction()) << *state
.AsValue();
472 TEST(SchedulerStateMachineTest
, TestNoCommitStatesRedrawWhenInvisible
) {
473 SchedulerSettings default_scheduler_settings
;
475 size_t num_commit_states
=
476 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
477 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
478 // There shouldn't be any drawing regardless of BeginFrame.
479 for (size_t j
= 0; j
< 2; ++j
) {
480 StateMachine
state(default_scheduler_settings
);
482 state
.UpdateState(state
.NextAction());
483 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
484 state
.SetCommitState(all_commit_states
[i
]);
485 state
.SetVisible(false);
486 state
.SetNeedsRedraw(true);
487 state
.SetNeedsForcedRedraw(false);
489 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
491 // Case 1: needs_commit=false.
492 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
,
495 // Case 2: needs_commit=true.
496 state
.SetNeedsCommit();
497 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
,
503 TEST(SchedulerStateMachineTest
, TestCanRedraw_StopsDraw
) {
504 SchedulerSettings default_scheduler_settings
;
506 size_t num_commit_states
=
507 sizeof(all_commit_states
) / sizeof(SchedulerStateMachine::CommitState
);
508 for (size_t i
= 0; i
< num_commit_states
; ++i
) {
509 // There shouldn't be any drawing regardless of BeginFrame.
510 for (size_t j
= 0; j
< 2; ++j
) {
511 StateMachine
state(default_scheduler_settings
);
513 state
.UpdateState(state
.NextAction());
514 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
515 state
.SetCommitState(all_commit_states
[i
]);
516 state
.SetVisible(false);
517 state
.SetNeedsRedraw(true);
518 state
.SetNeedsForcedRedraw(false);
520 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
522 state
.SetCanDraw(false);
523 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
,
529 TEST(SchedulerStateMachineTest
,
530 TestCanRedrawWithWaitingForFirstDrawMakesProgress
) {
531 SchedulerSettings default_scheduler_settings
;
532 StateMachine
state(default_scheduler_settings
);
534 state
.UpdateState(state
.NextAction());
535 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
536 state
.SetCommitState(
537 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
);
538 state
.SetNeedsCommit();
539 state
.SetNeedsRedraw(true);
540 state
.SetVisible(true);
541 state
.SetCanDraw(false);
542 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
,
544 state
.UpdateState(state
.NextAction());
545 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
549 TEST(SchedulerStateMachineTest
, TestsetNeedsCommitIsNotLost
) {
550 SchedulerSettings default_scheduler_settings
;
551 StateMachine
state(default_scheduler_settings
);
553 state
.UpdateState(state
.NextAction());
554 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
555 state
.SetNeedsCommit();
556 state
.SetVisible(true);
557 state
.SetCanDraw(true);
560 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
562 state
.UpdateState(state
.NextAction());
563 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
564 state
.CommitState());
566 // Now, while the frame is in progress, set another commit.
567 state
.SetNeedsCommit();
568 EXPECT_TRUE(state
.NeedsCommit());
570 // Let the frame finish.
571 state
.FinishCommit();
572 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
573 state
.CommitState());
575 // Expect to commit regardless of BeginFrame state.
576 state
.DidLeaveBeginFrame();
577 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
578 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
579 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
581 // Commit and make sure we draw on next BeginFrame
582 state
.UpdateState(SchedulerStateMachine::ACTION_COMMIT
);
583 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
, state
.NextAction());
584 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
,
585 state
.CommitState());
586 state
.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
);
587 state
.DidDrawIfPossibleCompleted(true);
589 // Verify that another commit will begin.
590 state
.DidLeaveBeginFrame();
591 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
595 TEST(SchedulerStateMachineTest
, TestFullCycle
) {
596 SchedulerSettings default_scheduler_settings
;
597 StateMachine
state(default_scheduler_settings
);
599 state
.UpdateState(state
.NextAction());
600 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
601 state
.SetVisible(true);
602 state
.SetCanDraw(true);
604 // Start clean and set commit.
605 state
.SetNeedsCommit();
606 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
611 SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
);
612 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
613 state
.CommitState());
614 EXPECT_FALSE(state
.NeedsCommit());
615 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
617 // Tell the scheduler the frame finished.
618 state
.FinishCommit();
619 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
620 state
.CommitState());
621 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
624 state
.UpdateState(SchedulerStateMachine::ACTION_COMMIT
);
625 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
,
626 state
.CommitState());
627 EXPECT_TRUE(state
.NeedsRedraw());
629 // Expect to do nothing until BeginFrame.
630 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
632 // At BeginFrame, draw.
633 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
634 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
, state
.NextAction());
635 state
.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
);
636 state
.DidDrawIfPossibleCompleted(true);
637 state
.DidLeaveBeginFrame();
639 // Should be synchronized, no draw needed, no action needed.
640 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
641 EXPECT_FALSE(state
.NeedsRedraw());
642 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
645 TEST(SchedulerStateMachineTest
, TestFullCycleWithCommitRequestInbetween
) {
646 SchedulerSettings default_scheduler_settings
;
647 StateMachine
state(default_scheduler_settings
);
649 state
.UpdateState(state
.NextAction());
650 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
651 state
.SetVisible(true);
652 state
.SetCanDraw(true);
654 // Start clean and set commit.
655 state
.SetNeedsCommit();
656 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
661 SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
);
662 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
663 state
.CommitState());
664 EXPECT_FALSE(state
.NeedsCommit());
665 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
667 // Request another commit while the commit is in flight.
668 state
.SetNeedsCommit();
669 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
671 // Tell the scheduler the frame finished.
672 state
.FinishCommit();
673 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
674 state
.CommitState());
675 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
678 state
.UpdateState(SchedulerStateMachine::ACTION_COMMIT
);
679 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
,
680 state
.CommitState());
681 EXPECT_TRUE(state
.NeedsRedraw());
683 // Expect to do nothing until BeginFrame.
684 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
686 // At BeginFrame, draw.
687 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
688 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
, state
.NextAction());
689 state
.UpdateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
);
690 state
.DidDrawIfPossibleCompleted(true);
691 state
.DidLeaveBeginFrame();
693 // Should be synchronized, no draw needed, no action needed.
694 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
695 EXPECT_FALSE(state
.NeedsRedraw());
696 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
700 TEST(SchedulerStateMachineTest
, TestRequestCommitInvisible
) {
701 SchedulerSettings default_scheduler_settings
;
702 StateMachine
state(default_scheduler_settings
);
704 state
.UpdateState(state
.NextAction());
705 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
706 state
.SetNeedsCommit();
707 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
710 TEST(SchedulerStateMachineTest
, TestGoesInvisibleBeforeFinishCommit
) {
711 SchedulerSettings default_scheduler_settings
;
712 StateMachine
state(default_scheduler_settings
);
714 state
.UpdateState(state
.NextAction());
715 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
716 state
.SetVisible(true);
717 state
.SetCanDraw(true);
719 // Start clean and set commit.
720 state
.SetNeedsCommit();
721 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
724 // Begin the frame while visible.
726 SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
);
727 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
728 state
.CommitState());
729 EXPECT_FALSE(state
.NeedsCommit());
730 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
732 // Become invisible and abort the main thread's begin frame.
733 state
.SetVisible(false);
734 state
.BeginFrameAbortedByMainThread(false);
736 // We should now be back in the idle state as if we didn't start a frame at
738 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
739 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
741 // Become visible again.
742 state
.SetVisible(true);
744 // Although we have aborted on this frame and haven't cancelled the commit
745 // (i.e. need another), don't send another begin frame yet.
746 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
747 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
748 EXPECT_TRUE(state
.NeedsCommit());
750 // Start a new frame.
751 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
752 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
756 state
.UpdateState(state
.NextAction());
758 // We should be starting the commit now.
759 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
760 state
.CommitState());
763 TEST(SchedulerStateMachineTest
, AbortBeginFrameAndCancelCommit
) {
764 SchedulerSettings default_scheduler_settings
;
765 StateMachine
state(default_scheduler_settings
);
767 state
.UpdateState(state
.NextAction());
768 state
.DidCreateAndInitializeOutputSurface();
769 state
.SetVisible(true);
770 state
.SetCanDraw(true);
772 // Get into a begin frame / commit state.
773 state
.SetNeedsCommit();
774 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
777 SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
);
778 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
779 state
.CommitState());
780 EXPECT_FALSE(state
.NeedsCommit());
781 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
783 // Abort the commit, cancelling future commits.
784 state
.BeginFrameAbortedByMainThread(true);
786 // Verify that another commit doesn't start on the same frame.
787 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
788 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
789 EXPECT_FALSE(state
.NeedsCommit());
791 // Start a new frame; draw because this is the first frame since output
793 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
794 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
, state
.NextAction())
796 state
.DidLeaveBeginFrame();
798 // Verify another commit doesn't start on another frame either.
799 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
800 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
801 EXPECT_FALSE(state
.NeedsCommit());
803 // Verify another commit can start if requested, though.
804 state
.SetNeedsCommit();
805 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
806 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
810 TEST(SchedulerStateMachineTest
, TestFirstContextCreation
) {
811 SchedulerSettings default_scheduler_settings
;
812 StateMachine
state(default_scheduler_settings
);
814 state
.SetVisible(true);
815 state
.SetCanDraw(true);
817 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
819 state
.UpdateState(state
.NextAction());
820 state
.DidCreateAndInitializeOutputSurface();
821 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
823 // Check that the first init does not SetNeedsCommit.
824 state
.SetNeedsCommit();
825 EXPECT_NE(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
828 TEST(SchedulerStateMachineTest
, TestContextLostWhenCompletelyIdle
) {
829 SchedulerSettings default_scheduler_settings
;
830 StateMachine
state(default_scheduler_settings
);
832 state
.UpdateState(state
.NextAction());
833 state
.DidCreateAndInitializeOutputSurface();
835 state
.SetVisible(true);
836 state
.SetCanDraw(true);
838 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
840 state
.DidLoseOutputSurface();
842 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
844 state
.UpdateState(state
.NextAction());
846 // Once context recreation begins, nothing should happen.
847 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
849 // Recreate the context.
850 state
.DidCreateAndInitializeOutputSurface();
852 // When the context is recreated, we should begin a commit.
853 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
855 state
.UpdateState(state
.NextAction());
858 TEST(SchedulerStateMachineTest
,
859 TestContextLostWhenIdleAndCommitRequestedWhileRecreating
) {
860 SchedulerSettings default_scheduler_settings
;
861 StateMachine
state(default_scheduler_settings
);
863 state
.UpdateState(state
.NextAction());
864 state
.DidCreateAndInitializeOutputSurface();
865 state
.SetVisible(true);
866 state
.SetCanDraw(true);
868 EXPECT_NE(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
870 state
.DidLoseOutputSurface();
872 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
874 state
.UpdateState(state
.NextAction());
876 // Once context recreation begins, nothing should happen.
877 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
879 // While context is recreating, commits shouldn't begin.
880 state
.SetNeedsCommit();
881 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
883 // Recreate the context
884 state
.DidCreateAndInitializeOutputSurface();
885 EXPECT_FALSE(state
.RedrawPending());
887 // When the context is recreated, we should begin a commit
888 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
890 state
.UpdateState(state
.NextAction());
891 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
892 state
.CommitState());
893 state
.FinishCommit();
894 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
895 state
.UpdateState(state
.NextAction());
896 // Finishing the first commit after initializing an output surface should
897 // automatically cause a redraw.
898 EXPECT_TRUE(state
.RedrawPending());
900 // Once the context is recreated, whether we draw should be based on
902 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
903 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
, state
.NextAction());
904 state
.SetCanDraw(false);
905 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
,
907 state
.SetCanDraw(true);
908 state
.DidLeaveBeginFrame();
911 TEST(SchedulerStateMachineTest
, TestContextLostWhileCommitInProgress
) {
912 SchedulerSettings default_scheduler_settings
;
913 StateMachine
state(default_scheduler_settings
);
915 state
.UpdateState(state
.NextAction());
916 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
917 state
.SetVisible(true);
918 state
.SetCanDraw(true);
920 // Get a commit in flight.
921 state
.SetNeedsCommit();
922 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
924 state
.UpdateState(state
.NextAction());
926 // Set damage and expect a draw.
927 state
.SetNeedsRedraw(true);
928 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
929 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
, state
.NextAction());
930 state
.UpdateState(state
.NextAction());
931 state
.DidLeaveBeginFrame();
933 // Cause a lost context while the begin frame is in flight
934 // for the main thread.
935 state
.DidLoseOutputSurface();
937 // Ask for another draw. Expect nothing happens.
938 state
.SetNeedsRedraw(true);
939 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
941 // Finish the frame, and commit.
942 state
.FinishCommit();
943 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
944 state
.UpdateState(state
.NextAction());
946 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
,
947 state
.CommitState());
949 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
,
951 state
.UpdateState(state
.NextAction());
953 // Expect to be told to begin context recreation, independent of
955 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
956 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
958 state
.DidLeaveBeginFrame();
959 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
963 TEST(SchedulerStateMachineTest
,
964 TestContextLostWhileCommitInProgressAndAnotherCommitRequested
) {
965 SchedulerSettings default_scheduler_settings
;
966 StateMachine
state(default_scheduler_settings
);
968 state
.UpdateState(state
.NextAction());
969 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
970 state
.SetVisible(true);
971 state
.SetCanDraw(true);
973 // Get a commit in flight.
974 state
.SetNeedsCommit();
975 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
977 state
.UpdateState(state
.NextAction());
979 // Set damage and expect a draw.
980 state
.SetNeedsRedraw(true);
981 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
982 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE
, state
.NextAction());
983 state
.UpdateState(state
.NextAction());
984 state
.DidLeaveBeginFrame();
986 // Cause a lost context while the begin frame is in flight
987 // for the main thread.
988 state
.DidLoseOutputSurface();
990 // Ask for another draw and also set needs commit. Expect nothing happens.
991 state
.SetNeedsRedraw(true);
992 state
.SetNeedsCommit();
993 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
995 // Finish the frame, and commit.
996 state
.FinishCommit();
997 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
998 state
.UpdateState(state
.NextAction());
1000 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
,
1001 state
.CommitState());
1003 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
,
1004 state
.NextAction());
1005 state
.UpdateState(state
.NextAction());
1007 // Expect to be told to begin context recreation, independent of
1009 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
1010 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1011 state
.NextAction());
1012 state
.DidLeaveBeginFrame();
1013 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1014 state
.NextAction());
1017 TEST(SchedulerStateMachineTest
, TestFinishAllRenderingWhileContextLost
) {
1018 SchedulerSettings default_scheduler_settings
;
1019 StateMachine
state(default_scheduler_settings
);
1020 state
.SetCanStart();
1021 state
.UpdateState(state
.NextAction());
1022 state
.DidCreateAndInitializeOutputSurface();
1023 state
.SetVisible(true);
1024 state
.SetCanDraw(true);
1026 // Cause a lost context lost.
1027 state
.DidLoseOutputSurface();
1029 // Ask a forced redraw and verify it ocurrs.
1030 state
.SetNeedsForcedRedraw(true);
1031 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
1032 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED
, state
.NextAction());
1033 state
.DidLeaveBeginFrame();
1035 // Clear the forced redraw bit.
1036 state
.SetNeedsForcedRedraw(false);
1038 // Expect to be told to begin context recreation, independent of
1040 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1041 state
.NextAction());
1042 state
.UpdateState(state
.NextAction());
1044 // Ask a forced redraw and verify it ocurrs.
1045 state
.SetNeedsForcedRedraw(true);
1046 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
1047 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED
, state
.NextAction());
1048 state
.DidLeaveBeginFrame();
1051 TEST(SchedulerStateMachineTest
, DontDrawBeforeCommitAfterLostOutputSurface
) {
1052 SchedulerSettings default_scheduler_settings
;
1053 StateMachine
state(default_scheduler_settings
);
1054 state
.SetCanStart();
1055 state
.UpdateState(state
.NextAction());
1056 state
.DidCreateAndInitializeOutputSurface();
1057 state
.SetVisible(true);
1058 state
.SetCanDraw(true);
1060 state
.SetNeedsRedraw(true);
1062 // Cause a lost output surface, and restore it.
1063 state
.DidLoseOutputSurface();
1064 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1065 state
.NextAction());
1066 state
.UpdateState(state
.NextAction());
1067 state
.DidCreateAndInitializeOutputSurface();
1069 EXPECT_FALSE(state
.RedrawPending());
1070 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
1071 state
.NextAction());
1074 TEST(SchedulerStateMachineTest
,
1075 TestSendBeginFrameToMainThreadWhenInvisibleAndForceCommit
) {
1076 SchedulerSettings default_scheduler_settings
;
1077 StateMachine
state(default_scheduler_settings
);
1078 state
.SetCanStart();
1079 state
.UpdateState(state
.NextAction());
1080 state
.DidCreateAndInitializeOutputSurface();
1081 state
.SetVisible(false);
1082 state
.SetNeedsCommit();
1083 state
.SetNeedsForcedCommit();
1084 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
1085 state
.NextAction());
1088 TEST(SchedulerStateMachineTest
,
1089 TestSendBeginFrameToMainThreadWhenCanStartFalseAndForceCommit
) {
1090 SchedulerSettings default_scheduler_settings
;
1091 StateMachine
state(default_scheduler_settings
);
1092 state
.SetVisible(true);
1093 state
.SetCanDraw(true);
1094 state
.SetNeedsCommit();
1095 state
.SetNeedsForcedCommit();
1096 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
1097 state
.NextAction());
1100 TEST(SchedulerStateMachineTest
, TestFinishCommitWhenCommitInProgress
) {
1101 SchedulerSettings default_scheduler_settings
;
1102 StateMachine
state(default_scheduler_settings
);
1103 state
.SetCanStart();
1104 state
.UpdateState(state
.NextAction());
1105 state
.DidCreateAndInitializeOutputSurface();
1106 state
.SetVisible(false);
1107 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
);
1108 state
.SetNeedsCommit();
1110 state
.FinishCommit();
1111 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
1112 state
.UpdateState(state
.NextAction());
1114 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
,
1115 state
.CommitState());
1116 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT
,
1117 state
.NextAction());
1118 state
.UpdateState(state
.NextAction());
1120 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1123 TEST(SchedulerStateMachineTest
, TestFinishCommitWhenForcedCommitInProgress
) {
1124 SchedulerSettings default_scheduler_settings
;
1125 StateMachine
state(default_scheduler_settings
);
1126 state
.SetCanStart();
1127 state
.UpdateState(state
.NextAction());
1128 state
.DidCreateAndInitializeOutputSurface();
1129 state
.SetVisible(false);
1130 state
.SetCommitState(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
);
1131 state
.SetNeedsCommit();
1132 state
.SetNeedsForcedCommit();
1134 state
.FinishCommit();
1135 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
1136 state
.UpdateState(state
.NextAction());
1138 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW
,
1139 state
.CommitState());
1141 // If we are waiting for forced draw then we know a begin frame is already
1142 // in flight for the main thread.
1143 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1146 TEST(SchedulerStateMachineTest
, TestInitialActionsWhenContextLost
) {
1147 SchedulerSettings default_scheduler_settings
;
1148 StateMachine
state(default_scheduler_settings
);
1149 state
.SetCanStart();
1150 state
.UpdateState(state
.NextAction());
1151 state
.DidCreateAndInitializeOutputSurface();
1152 state
.SetVisible(true);
1153 state
.SetCanDraw(true);
1154 state
.SetNeedsCommit();
1155 state
.DidLoseOutputSurface();
1157 // When we are visible, we normally want to begin output surface creation
1158 // as soon as possible.
1159 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION
,
1160 state
.NextAction()) << *state
.AsValue();
1161 state
.UpdateState(state
.NextAction());
1163 state
.DidCreateAndInitializeOutputSurface();
1164 EXPECT_EQ(state
.output_surface_state(),
1165 SchedulerStateMachine::OUTPUT_SURFACE_WAITING_FOR_FIRST_COMMIT
);
1167 // We should not send a BeginFrame to them main thread when we are invisible,
1168 // even if we've lost the output surface and are trying to get the first
1169 // commit, since the main thread will just abort anyway.
1170 state
.SetVisible(false);
1171 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
,
1172 state
.NextAction()) << *state
.AsValue();
1174 // If there is a forced commit, however, we could be blocking a readback
1175 // on the main thread, so we need to unblock it before we can get our
1176 // output surface, even if we are not visible.
1177 state
.SetNeedsForcedCommit();
1178 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
1179 state
.NextAction()) << *state
.AsValue();
1182 TEST(SchedulerStateMachineTest
, TestImmediateFinishCommit
) {
1183 SchedulerSettings default_scheduler_settings
;
1184 StateMachine
state(default_scheduler_settings
);
1185 state
.SetCanStart();
1186 state
.UpdateState(state
.NextAction());
1187 state
.DidCreateAndInitializeOutputSurface();
1188 state
.SetVisible(true);
1189 state
.SetCanDraw(true);
1191 // Schedule a forced frame, commit it, draw it.
1192 state
.SetNeedsCommit();
1193 state
.SetNeedsForcedCommit();
1194 state
.UpdateState(state
.NextAction());
1195 state
.FinishCommit();
1196 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
1197 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
1198 state
.CommitState());
1199 state
.UpdateState(state
.NextAction());
1201 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW
,
1202 state
.CommitState());
1204 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
1205 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1206 state
.SetNeedsForcedRedraw(true);
1207 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED
, state
.NextAction());
1208 state
.UpdateState(state
.NextAction());
1209 state
.DidDrawIfPossibleCompleted(true);
1210 state
.DidLeaveBeginFrame();
1212 // Should be waiting for the normal begin frame from the main thread.
1213 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
1214 state
.CommitState());
1217 TEST(SchedulerStateMachineTest
, TestImmediateFinishCommitDuringCommit
) {
1218 SchedulerSettings default_scheduler_settings
;
1219 StateMachine
state(default_scheduler_settings
);
1220 state
.SetCanStart();
1221 state
.UpdateState(state
.NextAction());
1222 state
.DidCreateAndInitializeOutputSurface();
1223 state
.SetVisible(true);
1224 state
.SetCanDraw(true);
1226 // Start a normal commit.
1227 state
.SetNeedsCommit();
1228 state
.UpdateState(state
.NextAction());
1230 // Schedule a forced frame, commit it, draw it.
1231 state
.SetNeedsCommit();
1232 state
.SetNeedsForcedCommit();
1233 state
.UpdateState(state
.NextAction());
1234 state
.FinishCommit();
1235 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
1236 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
1237 state
.CommitState());
1238 state
.UpdateState(state
.NextAction());
1240 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW
,
1241 state
.CommitState());
1243 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
1244 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1245 state
.SetNeedsForcedRedraw(true);
1246 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED
, state
.NextAction());
1247 state
.UpdateState(state
.NextAction());
1248 state
.DidDrawIfPossibleCompleted(true);
1249 state
.DidLeaveBeginFrame();
1251 // Should be waiting for the normal begin frame from the main thread.
1252 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
1253 state
.CommitState())
1254 << *state
.AsValue();
1257 TEST(SchedulerStateMachineTest
,
1258 ImmediateBeginFrameAbortedByMainThreadWhileInvisible
) {
1259 SchedulerSettings default_scheduler_settings
;
1260 StateMachine
state(default_scheduler_settings
);
1261 state
.SetCanStart();
1262 state
.UpdateState(state
.NextAction());
1263 state
.DidCreateAndInitializeOutputSurface();
1264 state
.SetVisible(true);
1265 state
.SetCanDraw(true);
1267 state
.SetNeedsCommit();
1268 state
.UpdateState(state
.NextAction());
1270 state
.SetNeedsCommit();
1271 state
.SetNeedsForcedCommit();
1272 state
.UpdateState(state
.NextAction());
1273 state
.FinishCommit();
1275 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
1276 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
1277 state
.CommitState());
1278 state
.UpdateState(state
.NextAction());
1280 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW
,
1281 state
.CommitState());
1283 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
1284 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1285 state
.SetNeedsForcedRedraw(true);
1286 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED
, state
.NextAction());
1287 state
.UpdateState(state
.NextAction());
1288 state
.DidDrawIfPossibleCompleted(true);
1289 state
.DidLeaveBeginFrame();
1291 // Should be waiting for the main thread's begin frame.
1292 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS
,
1293 state
.CommitState())
1294 << *state
.AsValue();
1296 // Become invisible and abort the main thread's begin frame.
1297 state
.SetVisible(false);
1298 state
.BeginFrameAbortedByMainThread(false);
1300 // Should be back in the idle state, but needing a commit.
1301 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE
, state
.CommitState());
1302 EXPECT_TRUE(state
.NeedsCommit());
1305 TEST(SchedulerStateMachineTest
, ImmediateFinishCommitWhileCantDraw
) {
1306 SchedulerSettings default_scheduler_settings
;
1307 StateMachine
state(default_scheduler_settings
);
1308 state
.SetCanStart();
1309 state
.UpdateState(state
.NextAction());
1310 state
.DidCreateAndInitializeOutputSurface();
1311 state
.SetVisible(true);
1312 state
.SetCanDraw(false);
1314 state
.SetNeedsCommit();
1315 state
.UpdateState(state
.NextAction());
1317 state
.SetNeedsCommit();
1318 state
.SetNeedsForcedCommit();
1319 state
.UpdateState(state
.NextAction());
1320 state
.FinishCommit();
1322 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
1323 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT
,
1324 state
.CommitState());
1325 state
.UpdateState(state
.NextAction());
1327 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW
,
1328 state
.CommitState());
1330 state
.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
1331 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1332 state
.SetNeedsForcedRedraw(true);
1333 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED
, state
.NextAction());
1334 state
.UpdateState(state
.NextAction());
1335 state
.DidDrawIfPossibleCompleted(true);
1336 state
.DidLeaveBeginFrame();
1339 TEST(SchedulerStateMachineTest
, ReportIfNotDrawing
) {
1340 SchedulerSettings default_scheduler_settings
;
1341 StateMachine
state(default_scheduler_settings
);
1342 state
.SetCanStart();
1343 state
.UpdateState(state
.NextAction());
1344 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1346 state
.SetCanDraw(true);
1347 state
.SetVisible(true);
1348 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1350 state
.SetCanDraw(false);
1351 state
.SetVisible(true);
1352 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1354 state
.SetCanDraw(true);
1355 state
.SetVisible(false);
1356 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1358 state
.SetCanDraw(false);
1359 state
.SetVisible(false);
1360 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1362 state
.SetCanDraw(true);
1363 state
.SetVisible(true);
1364 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1367 TEST(SchedulerStateMachineTest
, ReportIfNotDrawingFromAcquiredTextures
) {
1368 SchedulerSettings default_scheduler_settings
;
1369 StateMachine
state(default_scheduler_settings
);
1370 state
.SetCanStart();
1371 state
.UpdateState(state
.NextAction());
1372 state
.CreateAndInitializeOutputSurfaceWithActivatedCommit();
1373 state
.SetCanDraw(true);
1374 state
.SetVisible(true);
1375 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1377 state
.SetMainThreadNeedsLayerTextures();
1379 SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD
,
1380 state
.NextAction());
1381 state
.UpdateState(state
.NextAction());
1382 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1384 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1386 state
.SetNeedsCommit();
1387 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
1388 state
.NextAction());
1390 state
.UpdateState(state
.NextAction());
1391 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1393 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1395 state
.FinishCommit();
1396 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1398 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT
, state
.NextAction());
1400 state
.UpdateState(state
.NextAction());
1401 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());
1404 TEST(SchedulerStateMachineTest
, AcquireTexturesWithAbort
) {
1405 SchedulerSettings default_scheduler_settings
;
1406 SchedulerStateMachine
state(default_scheduler_settings
);
1407 state
.SetCanStart();
1408 state
.UpdateState(state
.NextAction());
1409 state
.DidCreateAndInitializeOutputSurface();
1410 state
.SetCanDraw(true);
1411 state
.SetVisible(true);
1413 state
.SetMainThreadNeedsLayerTextures();
1415 SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD
,
1416 state
.NextAction());
1417 state
.UpdateState(state
.NextAction());
1418 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1420 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1422 state
.SetNeedsCommit();
1423 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD
,
1424 state
.NextAction());
1425 state
.UpdateState(state
.NextAction());
1426 EXPECT_TRUE(state
.PendingDrawsShouldBeAborted());
1428 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1430 state
.BeginFrameAbortedByMainThread(true);
1432 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE
, state
.NextAction());
1433 EXPECT_FALSE(state
.PendingDrawsShouldBeAborted());