cc: Added inline to Tile::IsReadyToDraw
[chromium-blink-merge.git] / cc / scheduler / scheduler_state_machine_unittest.cc
blob53a2e09686c701dd48cdaea8e74dba93c231e227
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"
10 namespace cc {
12 namespace {
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 {
23 public:
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);
57 state.SetCanStart();
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);
93 state.SetCanStart();
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);
102 state.SetCanStart();
103 state.UpdateState(state.NextAction());
104 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
105 state.SetVisible(true);
106 state.UpdateState(
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);
128 state.SetCanStart();
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,
148 state.NextAction());
149 state.UpdateState(
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);
159 state.SetCanStart();
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,
185 state.NextAction());
186 EXPECT_TRUE(state.RedrawPending());
189 TEST(SchedulerStateMachineTest,
190 TestCommitAfterFailedDrawAllowsDrawInSameFrame) {
191 SchedulerSettings default_scheduler_settings;
192 StateMachine state(default_scheduler_settings);
193 state.SetCanStart();
194 state.UpdateState(state.NextAction());
195 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
196 state.SetVisible(true);
197 state.SetCanDraw(true);
199 // Start a commit.
200 state.SetNeedsCommit();
201 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD,
202 state.NextAction());
203 state.UpdateState(
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());
214 // Fail the draw.
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);
236 state.SetCanStart();
237 state.UpdateState(state.NextAction());
238 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
239 state.SetVisible(true);
240 state.SetCanDraw(true);
242 // Start a commit.
243 state.SetNeedsCommit();
244 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD,
245 state.NextAction());
246 state.UpdateState(
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());
257 // Fail the draw.
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());
265 // Force a draw.
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);
290 state.SetCanStart();
291 state.UpdateState(state.NextAction());
292 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
293 state.SetVisible(true);
294 state.SetCanDraw(true);
295 state.SetMaximumNumberOfFailedDrawsBeforeDrawIsForced(1);
297 // Start a commit.
298 state.SetNeedsCommit();
299 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD,
300 state.NextAction());
301 state.UpdateState(
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());
312 // Fail the draw.
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);
335 state.SetCanStart();
336 state.UpdateState(state.NextAction());
337 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
338 state.SetVisible(true);
339 state.SetCanDraw(true);
341 // Start a draw.
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());
348 // Fail the draw.
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,
356 state.NextAction());
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);
369 state.SetCanStart();
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,
401 // don't draw.
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);
407 state.SetCanStart();
408 state.UpdateState(state.NextAction());
409 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
410 state.SetCommitState(all_commit_states[i]);
411 bool visible = j;
412 if (!visible) {
413 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
414 state.SetVisible(false);
415 } else {
416 state.SetVisible(true);
419 // Case 1: needs_commit=false
420 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE,
421 state.NextAction());
423 // Case 2: needs_commit=true
424 state.SetNeedsCommit();
425 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE,
426 state.NextAction());
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
432 // commit.
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);
436 state.SetCanStart();
437 state.UpdateState(state.NextAction());
438 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
439 state.SetCanDraw(true);
440 state.SetCommitState(all_commit_states[i]);
441 bool forced_draw = j;
442 if (!forced_draw) {
443 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
444 state.SetNeedsRedraw(true);
445 state.SetVisible(true);
446 } else {
447 state.SetNeedsForcedRedraw(true);
450 SchedulerStateMachine::Action expected_action;
451 if (all_commit_states[i] !=
452 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT) {
453 expected_action =
454 forced_draw ? SchedulerStateMachine::ACTION_DRAW_FORCED
455 : SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE;
456 } else {
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);
481 state.SetCanStart();
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);
488 if (j == 1)
489 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
491 // Case 1: needs_commit=false.
492 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE,
493 state.NextAction());
495 // Case 2: needs_commit=true.
496 state.SetNeedsCommit();
497 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE,
498 state.NextAction());
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);
512 state.SetCanStart();
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);
519 if (j == 1)
520 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
522 state.SetCanDraw(false);
523 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE,
524 state.NextAction());
529 TEST(SchedulerStateMachineTest,
530 TestCanRedrawWithWaitingForFirstDrawMakesProgress) {
531 SchedulerSettings default_scheduler_settings;
532 StateMachine state(default_scheduler_settings);
533 state.SetCanStart();
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,
543 state.NextAction());
544 state.UpdateState(state.NextAction());
545 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD,
546 state.NextAction());
549 TEST(SchedulerStateMachineTest, TestsetNeedsCommitIsNotLost) {
550 SchedulerSettings default_scheduler_settings;
551 StateMachine state(default_scheduler_settings);
552 state.SetCanStart();
553 state.UpdateState(state.NextAction());
554 state.CreateAndInitializeOutputSurfaceWithActivatedCommit();
555 state.SetNeedsCommit();
556 state.SetVisible(true);
557 state.SetCanDraw(true);
559 // Begin the frame.
560 EXPECT_EQ(SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD,
561 state.NextAction());
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,
592 state.NextAction());
595 TEST(SchedulerStateMachineTest, TestFullCycle) {
596 SchedulerSettings default_scheduler_settings;
597 StateMachine state(default_scheduler_settings);
598 state.SetCanStart();
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,
607 state.NextAction());
609 // Begin the frame.
610 state.UpdateState(
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());
623 // Commit.
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);
648 state.SetCanStart();
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,
657 state.NextAction());
659 // Begin the frame.
660 state.UpdateState(
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());
677 // Commit.
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,
697 state.NextAction());
700 TEST(SchedulerStateMachineTest, TestRequestCommitInvisible) {
701 SchedulerSettings default_scheduler_settings;
702 StateMachine state(default_scheduler_settings);
703 state.SetCanStart();
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);
713 state.SetCanStart();
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,
722 state.NextAction());
724 // Begin the frame while visible.
725 state.UpdateState(
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
737 // all.
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,
753 state.NextAction());
755 // Begin the frame.
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);
766 state.SetCanStart();
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,
775 state.NextAction());
776 state.UpdateState(
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
792 // surface init'd.
793 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
794 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction())
795 << *state.AsValue();
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,
807 state.NextAction());
810 TEST(SchedulerStateMachineTest, TestFirstContextCreation) {
811 SchedulerSettings default_scheduler_settings;
812 StateMachine state(default_scheduler_settings);
813 state.SetCanStart();
814 state.SetVisible(true);
815 state.SetCanDraw(true);
817 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
818 state.NextAction());
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);
831 state.SetCanStart();
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,
839 state.NextAction());
840 state.DidLoseOutputSurface();
842 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
843 state.NextAction());
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,
854 state.NextAction());
855 state.UpdateState(state.NextAction());
858 TEST(SchedulerStateMachineTest,
859 TestContextLostWhenIdleAndCommitRequestedWhileRecreating) {
860 SchedulerSettings default_scheduler_settings;
861 StateMachine state(default_scheduler_settings);
862 state.SetCanStart();
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,
869 state.NextAction());
870 state.DidLoseOutputSurface();
872 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
873 state.NextAction());
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,
889 state.NextAction());
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
901 // SetCanDraw.
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,
906 state.NextAction());
907 state.SetCanDraw(true);
908 state.DidLeaveBeginFrame();
911 TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) {
912 SchedulerSettings default_scheduler_settings;
913 StateMachine state(default_scheduler_settings);
914 state.SetCanStart();
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,
923 state.NextAction());
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,
950 state.NextAction());
951 state.UpdateState(state.NextAction());
953 // Expect to be told to begin context recreation, independent of
954 // BeginFrame state.
955 state.DidEnterBeginFrame(BeginFrameArgs::CreateForTesting());
956 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
957 state.NextAction());
958 state.DidLeaveBeginFrame();
959 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION,
960 state.NextAction());
963 TEST(SchedulerStateMachineTest,
964 TestContextLostWhileCommitInProgressAndAnotherCommitRequested) {
965 SchedulerSettings default_scheduler_settings;
966 StateMachine state(default_scheduler_settings);
967 state.SetCanStart();
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,
976 state.NextAction());
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
1008 // BeginFrame state
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
1039 // BeginFrame state
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();
1378 EXPECT_EQ(
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();
1414 EXPECT_EQ(
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());
1436 } // namespace
1437 } // namespace cc