Add Sad Tab resources to the iOS build.
[chromium-blink-merge.git] / cc / scheduler_state_machine_unittest.cc
blobf392e853c104f46937530e7dfe4be94b86b5be41
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 "config.h"
7 #include "cc/scheduler_state_machine.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 using namespace cc;
13 namespace {
15 const SchedulerStateMachine::CommitState allCommitStates[] = {
16 SchedulerStateMachine::COMMIT_STATE_IDLE,
17 SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS,
18 SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
19 SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
22 // Exposes the protected state fields of the SchedulerStateMachine for testing
23 class StateMachine : public SchedulerStateMachine {
24 public:
25 void setCommitState(CommitState cs) { m_commitState = cs; }
26 CommitState commitState() const { return m_commitState; }
28 void setNeedsCommit(bool b) { m_needsCommit = b; }
29 bool needsCommit() const { return m_needsCommit; }
31 void setNeedsForcedCommit(bool b) { m_needsForcedCommit = b; }
32 bool needsForcedCommit() const { return m_needsForcedCommit; }
34 void setNeedsRedraw(bool b) { m_needsRedraw = b; }
35 bool needsRedraw() const { return m_needsRedraw; }
37 void setNeedsForcedRedraw(bool b) { m_needsForcedRedraw = b; }
38 bool needsForcedRedraw() const { return m_needsForcedRedraw; }
40 bool canDraw() const { return m_canDraw; }
41 bool insideVSync() const { return m_insideVSync; }
42 bool visible() const { return m_visible; }
45 TEST(SchedulerStateMachineTest, TestNextActionBeginsFrameIfNeeded)
47 // If no commit needed, do nothing
49 StateMachine state;
50 state.setCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
51 state.setCanBeginFrame(true);
52 state.setNeedsRedraw(false);
53 state.setNeedsCommit(false);
54 state.setVisible(true);
56 EXPECT_FALSE(state.vsyncCallbackNeeded());
58 state.didLeaveVSync();
59 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
60 EXPECT_FALSE(state.vsyncCallbackNeeded());
61 state.didEnterVSync();
62 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
65 // If commit requested but canBeginFrame is still false, do nothing.
67 StateMachine state;
68 state.setCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
69 state.setNeedsRedraw(false);
70 state.setNeedsCommit(false);
71 state.setVisible(true);
73 EXPECT_FALSE(state.vsyncCallbackNeeded());
75 state.didLeaveVSync();
76 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
77 EXPECT_FALSE(state.vsyncCallbackNeeded());
78 state.didEnterVSync();
79 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
83 // If commit requested, begin a frame
85 StateMachine state;
86 state.setCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
87 state.setCanBeginFrame(true);
88 state.setNeedsRedraw(false);
89 state.setNeedsCommit(true);
90 state.setVisible(true);
91 EXPECT_FALSE(state.vsyncCallbackNeeded());
94 // Begin the frame, make sure needsCommit and commitState update correctly.
96 StateMachine state;
97 state.setCanBeginFrame(true);
98 state.setVisible(true);
99 state.updateState(SchedulerStateMachine::ACTION_BEGIN_FRAME);
100 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState());
101 EXPECT_FALSE(state.needsCommit());
102 EXPECT_FALSE(state.vsyncCallbackNeeded());
106 TEST(SchedulerStateMachineTest, TestSetForcedRedrawDoesNotSetsNormalRedraw)
108 SchedulerStateMachine state;
109 state.setCanDraw(true);
110 state.setNeedsForcedRedraw();
111 EXPECT_FALSE(state.redrawPending());
112 EXPECT_TRUE(state.vsyncCallbackNeeded());
115 TEST(SchedulerStateMachineTest, TestFailedDrawSetsNeedsCommitAndDoesNotDrawAgain)
117 SchedulerStateMachine state;
118 state.setCanBeginFrame(true);
119 state.setVisible(true);
120 state.setCanDraw(true);
121 state.setNeedsRedraw();
122 EXPECT_TRUE(state.redrawPending());
123 EXPECT_TRUE(state.vsyncCallbackNeeded());
124 state.didEnterVSync();
126 // We're drawing now.
127 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
128 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
129 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
130 EXPECT_FALSE(state.redrawPending());
131 EXPECT_FALSE(state.commitPending());
133 // Failing the draw makes us require a commit.
134 state.didDrawIfPossibleCompleted(false);
135 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
136 state.updateState(SchedulerStateMachine::ACTION_BEGIN_FRAME);
137 EXPECT_TRUE(state.redrawPending());
138 EXPECT_TRUE(state.commitPending());
141 TEST(SchedulerStateMachineTest, TestSetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw)
143 SchedulerStateMachine state;
144 state.setCanBeginFrame(true);
145 state.setVisible(true);
146 state.setCanDraw(true);
147 state.setNeedsRedraw();
148 EXPECT_TRUE(state.redrawPending());
149 EXPECT_TRUE(state.vsyncCallbackNeeded());
150 state.didEnterVSync();
152 // We're drawing now.
153 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
154 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
155 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
156 EXPECT_FALSE(state.redrawPending());
157 EXPECT_FALSE(state.commitPending());
159 // While still in the same vsync callback, set needs redraw again.
160 // This should not redraw.
161 state.setNeedsRedraw();
162 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
164 // Failing the draw makes us require a commit.
165 state.didDrawIfPossibleCompleted(false);
166 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
167 EXPECT_TRUE(state.redrawPending());
170 TEST(SchedulerStateMachineTest, TestCommitAfterFailedDrawAllowsDrawInSameFrame)
172 SchedulerStateMachine state;
173 state.setCanBeginFrame(true);
174 state.setVisible(true);
175 state.setCanDraw(true);
177 // Start a commit.
178 state.setNeedsCommit();
179 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
180 state.updateState(SchedulerStateMachine::ACTION_BEGIN_FRAME);
181 EXPECT_TRUE(state.commitPending());
183 // Then initiate a draw.
184 state.setNeedsRedraw();
185 EXPECT_TRUE(state.vsyncCallbackNeeded());
186 state.didEnterVSync();
187 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
188 EXPECT_TRUE(state.redrawPending());
190 // Fail the draw.
191 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
192 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
193 state.didDrawIfPossibleCompleted(false);
194 EXPECT_TRUE(state.redrawPending());
195 // But the commit is ongoing.
196 EXPECT_TRUE(state.commitPending());
198 // Finish the commit.
199 state.beginFrameComplete();
200 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
201 state.updateState(SchedulerStateMachine::ACTION_COMMIT);
202 EXPECT_TRUE(state.redrawPending());
204 // And we should be allowed to draw again.
205 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
208 TEST(SchedulerStateMachineTest, TestCommitAfterFailedAndSuccessfulDrawDoesNotAllowDrawInSameFrame)
210 SchedulerStateMachine state;
211 state.setCanBeginFrame(true);
212 state.setVisible(true);
213 state.setCanDraw(true);
215 // Start a commit.
216 state.setNeedsCommit();
217 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
218 state.updateState(SchedulerStateMachine::ACTION_BEGIN_FRAME);
219 EXPECT_TRUE(state.commitPending());
221 // Then initiate a draw.
222 state.setNeedsRedraw();
223 EXPECT_TRUE(state.vsyncCallbackNeeded());
224 state.didEnterVSync();
225 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
226 EXPECT_TRUE(state.redrawPending());
228 // Fail the draw.
229 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
230 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
231 state.didDrawIfPossibleCompleted(false);
232 EXPECT_TRUE(state.redrawPending());
233 // But the commit is ongoing.
234 EXPECT_TRUE(state.commitPending());
236 // Force a draw.
237 state.setNeedsForcedRedraw();
238 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.nextAction());
240 // Do the forced draw.
241 state.updateState(SchedulerStateMachine::ACTION_DRAW_FORCED);
242 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
243 EXPECT_FALSE(state.redrawPending());
244 // And the commit is still ongoing.
245 EXPECT_TRUE(state.commitPending());
247 // Finish the commit.
248 state.beginFrameComplete();
249 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
250 state.updateState(SchedulerStateMachine::ACTION_COMMIT);
251 EXPECT_TRUE(state.redrawPending());
253 // And we should not be allowed to draw again in the same frame..
254 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
257 TEST(SchedulerStateMachineTest, TestFailedDrawsWillEventuallyForceADrawAfterTheNextCommit)
259 SchedulerStateMachine state;
260 state.setCanBeginFrame(true);
261 state.setVisible(true);
262 state.setCanDraw(true);
263 state.setMaximumNumberOfFailedDrawsBeforeDrawIsForced(1);
265 // Start a commit.
266 state.setNeedsCommit();
267 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
268 state.updateState(SchedulerStateMachine::ACTION_BEGIN_FRAME);
269 EXPECT_TRUE(state.commitPending());
271 // Then initiate a draw.
272 state.setNeedsRedraw();
273 EXPECT_TRUE(state.vsyncCallbackNeeded());
274 state.didEnterVSync();
275 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
276 EXPECT_TRUE(state.redrawPending());
278 // Fail the draw.
279 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
280 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
281 state.didDrawIfPossibleCompleted(false);
282 EXPECT_TRUE(state.redrawPending());
283 // But the commit is ongoing.
284 EXPECT_TRUE(state.commitPending());
286 // Finish the commit. Note, we should not yet be forcing a draw, but should
287 // continue the commit as usual.
288 state.beginFrameComplete();
289 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
290 state.updateState(SchedulerStateMachine::ACTION_COMMIT);
291 EXPECT_TRUE(state.redrawPending());
293 // The redraw should be forced in this case.
294 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.nextAction());
297 TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedNextVSync)
299 SchedulerStateMachine state;
300 state.setCanBeginFrame(true);
301 state.setVisible(true);
302 state.setCanDraw(true);
304 // Start a draw.
305 state.setNeedsRedraw();
306 EXPECT_TRUE(state.vsyncCallbackNeeded());
307 state.didEnterVSync();
308 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
309 EXPECT_TRUE(state.redrawPending());
311 // Fail the draw.
312 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
313 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
314 state.didDrawIfPossibleCompleted(false);
315 EXPECT_TRUE(state.redrawPending());
317 // We should not be trying to draw again now, but we have a commit pending.
318 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
320 state.didLeaveVSync();
321 EXPECT_TRUE(state.vsyncCallbackNeeded());
322 state.didEnterVSync();
324 // We should try draw again in the next vsync.
325 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
328 TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame)
330 SchedulerStateMachine state;
331 state.setVisible(true);
332 state.setCanDraw(true);
333 state.setNeedsRedraw();
334 EXPECT_TRUE(state.vsyncCallbackNeeded());
335 state.didEnterVSync();
336 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
337 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
339 // While still in the same vsync callback, set needs redraw again.
340 // This should not redraw.
341 state.setNeedsRedraw();
342 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
344 // Move to another frame. This should now draw.
345 state.didDrawIfPossibleCompleted(true);
346 state.didLeaveVSync();
347 EXPECT_TRUE(state.vsyncCallbackNeeded());
348 state.didEnterVSync();
350 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
351 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
352 state.didDrawIfPossibleCompleted(true);
353 EXPECT_FALSE(state.vsyncCallbackNeeded());
356 TEST(SchedulerStateMachineTest, TestNextActionDrawsOnVSync)
358 // When not on vsync, or on vsync but not visible, don't draw.
359 size_t numCommitStates = sizeof(allCommitStates) / sizeof(SchedulerStateMachine::CommitState);
360 for (size_t i = 0; i < numCommitStates; ++i) {
361 for (unsigned j = 0; j < 2; ++j) {
362 StateMachine state;
363 state.setCommitState(allCommitStates[i]);
364 bool visible = j;
365 if (!visible) {
366 state.didEnterVSync();
367 state.setVisible(false);
368 } else
369 state.setVisible(true);
371 // Case 1: needsCommit=false
372 state.setNeedsCommit(false);
373 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
375 // Case 2: needsCommit=true
376 state.setNeedsCommit(true);
377 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
381 // When on vsync, or not on vsync but needsForcedRedraw set, should always draw except if you're ready to commit, in which case commit.
382 for (size_t i = 0; i < numCommitStates; ++i) {
383 for (unsigned j = 0; j < 2; ++j) {
384 StateMachine state;
385 state.setCanDraw(true);
386 state.setCommitState(allCommitStates[i]);
387 bool forcedDraw = j;
388 if (!forcedDraw) {
389 state.didEnterVSync();
390 state.setNeedsRedraw(true);
391 state.setVisible(true);
392 } else
393 state.setNeedsForcedRedraw(true);
395 SchedulerStateMachine::Action expectedAction;
396 if (allCommitStates[i] != SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT)
397 expectedAction = forcedDraw ? SchedulerStateMachine::ACTION_DRAW_FORCED : SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE;
398 else
399 expectedAction = SchedulerStateMachine::ACTION_COMMIT;
401 // Case 1: needsCommit=false.
402 state.setNeedsCommit(false);
403 EXPECT_TRUE(state.vsyncCallbackNeeded());
404 EXPECT_EQ(expectedAction, state.nextAction());
406 // Case 2: needsCommit=true.
407 state.setNeedsCommit(true);
408 EXPECT_TRUE(state.vsyncCallbackNeeded());
409 EXPECT_EQ(expectedAction, state.nextAction());
414 TEST(SchedulerStateMachineTest, TestNoCommitStatesRedrawWhenInvisible)
416 size_t numCommitStates = sizeof(allCommitStates) / sizeof(SchedulerStateMachine::CommitState);
417 for (size_t i = 0; i < numCommitStates; ++i) {
418 // There shouldn't be any drawing regardless of vsync.
419 for (unsigned j = 0; j < 2; ++j) {
420 StateMachine state;
421 state.setCommitState(allCommitStates[i]);
422 state.setVisible(false);
423 state.setNeedsRedraw(true);
424 state.setNeedsForcedRedraw(false);
425 if (j == 1)
426 state.didEnterVSync();
428 // Case 1: needsCommit=false.
429 state.setNeedsCommit(false);
430 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
432 // Case 2: needsCommit=true.
433 state.setNeedsCommit(true);
434 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
439 TEST(SchedulerStateMachineTest, TestCanRedraw_StopsDraw)
441 size_t numCommitStates = sizeof(allCommitStates) / sizeof(SchedulerStateMachine::CommitState);
442 for (size_t i = 0; i < numCommitStates; ++i) {
443 // There shouldn't be any drawing regardless of vsync.
444 for (unsigned j = 0; j < 2; ++j) {
445 StateMachine state;
446 state.setCommitState(allCommitStates[i]);
447 state.setVisible(false);
448 state.setNeedsRedraw(true);
449 state.setNeedsForcedRedraw(false);
450 if (j == 1)
451 state.didEnterVSync();
453 state.setCanDraw(false);
454 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
459 TEST(SchedulerStateMachineTest, TestCanRedrawWithWaitingForFirstDrawMakesProgress)
461 StateMachine state;
462 state.setCommitState(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
463 state.setCanBeginFrame(true);
464 state.setNeedsCommit(true);
465 state.setNeedsRedraw(true);
466 state.setVisible(true);
467 state.setCanDraw(false);
468 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
471 TEST(SchedulerStateMachineTest, TestSetNeedsCommitIsNotLost)
473 StateMachine state;
474 state.setCanBeginFrame(true);
475 state.setNeedsCommit(true);
476 state.setVisible(true);
477 state.setCanDraw(true);
479 // Begin the frame.
480 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
481 state.updateState(state.nextAction());
482 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState());
484 // Now, while the frame is in progress, set another commit.
485 state.setNeedsCommit(true);
486 EXPECT_TRUE(state.needsCommit());
488 // Let the frame finish.
489 state.beginFrameComplete();
490 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, state.commitState());
492 // Expect to commit regardless of vsync state.
493 state.didLeaveVSync();
494 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
495 state.didEnterVSync();
496 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
498 // Commit and make sure we draw on next vsync
499 state.updateState(SchedulerStateMachine::ACTION_COMMIT);
500 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
501 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, state.commitState());
502 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
503 state.didDrawIfPossibleCompleted(true);
505 // Verify that another commit will begin.
506 state.didLeaveVSync();
507 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
510 TEST(SchedulerStateMachineTest, TestFullCycle)
512 StateMachine state;
513 state.setCanBeginFrame(true);
514 state.setVisible(true);
515 state.setCanDraw(true);
517 // Start clean and set commit.
518 state.setNeedsCommit(true);
519 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
521 // Begin the frame.
522 state.updateState(SchedulerStateMachine::ACTION_BEGIN_FRAME);
523 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState());
524 EXPECT_FALSE(state.needsCommit());
525 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
527 // Tell the scheduler the frame finished.
528 state.beginFrameComplete();
529 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, state.commitState());
530 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
532 // Commit.
533 state.updateState(SchedulerStateMachine::ACTION_COMMIT);
534 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, state.commitState());
535 EXPECT_TRUE(state.needsRedraw());
537 // Expect to do nothing until vsync.
538 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
540 // At vsync, draw.
541 state.didEnterVSync();
542 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
543 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
544 state.didDrawIfPossibleCompleted(true);
545 state.didLeaveVSync();
547 // Should be synchronized, no draw needed, no action needed.
548 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.commitState());
549 EXPECT_FALSE(state.needsRedraw());
550 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
553 TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween)
555 StateMachine state;
556 state.setCanBeginFrame(true);
557 state.setVisible(true);
558 state.setCanDraw(true);
560 // Start clean and set commit.
561 state.setNeedsCommit(true);
562 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
564 // Begin the frame.
565 state.updateState(SchedulerStateMachine::ACTION_BEGIN_FRAME);
566 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState());
567 EXPECT_FALSE(state.needsCommit());
568 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
570 // Request another commit while the commit is in flight.
571 state.setNeedsCommit(true);
572 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
574 // Tell the scheduler the frame finished.
575 state.beginFrameComplete();
576 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, state.commitState());
577 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
579 // Commit.
580 state.updateState(SchedulerStateMachine::ACTION_COMMIT);
581 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, state.commitState());
582 EXPECT_TRUE(state.needsRedraw());
584 // Expect to do nothing until vsync.
585 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
587 // At vsync, draw.
588 state.didEnterVSync();
589 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
590 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
591 state.didDrawIfPossibleCompleted(true);
592 state.didLeaveVSync();
594 // Should be synchronized, no draw needed, no action needed.
595 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.commitState());
596 EXPECT_FALSE(state.needsRedraw());
597 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
600 TEST(SchedulerStateMachineTest, TestRequestCommitInvisible)
602 StateMachine state;
603 state.setNeedsCommit(true);
604 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
607 TEST(SchedulerStateMachineTest, TestGoesInvisibleBeforeBeginFrameCompletes)
609 StateMachine state;
610 state.setCanBeginFrame(true);
611 state.setVisible(true);
612 state.setCanDraw(true);
614 // Start clean and set commit.
615 state.setNeedsCommit(true);
616 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
618 // Begin the frame while visible.
619 state.updateState(SchedulerStateMachine::ACTION_BEGIN_FRAME);
620 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState());
621 EXPECT_FALSE(state.needsCommit());
622 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
624 // Become invisible and abort the beginFrame.
625 state.setVisible(false);
626 state.beginFrameAborted();
628 // We should now be back in the idle state as if we didn't start a frame at all.
629 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.commitState());
630 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
632 // Become visible again
633 state.setVisible(true);
635 // We should be beginning a frame now
636 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.commitState());
637 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
639 // Begin the frame
640 state.updateState(state.nextAction());
642 // We should be starting the commit now
643 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState());
646 TEST(SchedulerStateMachineTest, TestContextLostWhenCompletelyIdle)
648 StateMachine state;
649 state.setCanBeginFrame(true);
650 state.setVisible(true);
651 state.setCanDraw(true);
653 state.didLoseContext();
655 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_CONTEXT_RECREATION, state.nextAction());
656 state.updateState(state.nextAction());
658 // Once context recreation begins, nothing should happen.
659 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
661 // Recreate the context
662 state.didRecreateContext();
664 // When the context is recreated, we should begin a commit
665 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
666 state.updateState(state.nextAction());
669 TEST(SchedulerStateMachineTest, TestContextLostWhenIdleAndCommitRequestedWhileRecreating)
671 StateMachine state;
672 state.setCanBeginFrame(true);
673 state.setVisible(true);
674 state.setCanDraw(true);
676 state.didLoseContext();
678 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_CONTEXT_RECREATION, state.nextAction());
679 state.updateState(state.nextAction());
681 // Once context recreation begins, nothing should happen.
682 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
684 // While context is recreating, commits shouldn't begin.
685 state.setNeedsCommit(true);
686 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
688 // Recreate the context
689 state.didRecreateContext();
691 // When the context is recreated, we should begin a commit
692 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
693 state.updateState(state.nextAction());
695 // Once the context is recreated, whether we draw should be based on
696 // setCanDraw.
697 state.setNeedsRedraw(true);
698 state.didEnterVSync();
699 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
700 state.setCanDraw(false);
701 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
702 state.setCanDraw(true);
703 state.didLeaveVSync();
706 TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress)
708 StateMachine state;
709 state.setCanBeginFrame(true);
710 state.setVisible(true);
711 state.setCanDraw(true);
713 // Get a commit in flight.
714 state.setNeedsCommit(true);
715 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
716 state.updateState(state.nextAction());
718 // Set damage and expect a draw.
719 state.setNeedsRedraw(true);
720 state.didEnterVSync();
721 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
722 state.updateState(state.nextAction());
723 state.didLeaveVSync();
725 // Cause a lost context while the begin frame is in flight.
726 state.didLoseContext();
728 // Ask for another draw. Expect nothing happens.
729 state.setNeedsRedraw(true);
730 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
732 // Finish the frame, and commit.
733 state.beginFrameComplete();
734 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
735 state.updateState(state.nextAction());
737 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, state.commitState());
739 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
740 state.updateState(state.nextAction());
742 // Expect to be told to begin context recreation, independent of vsync state
743 state.didEnterVSync();
744 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_CONTEXT_RECREATION, state.nextAction());
745 state.didLeaveVSync();
746 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_CONTEXT_RECREATION, state.nextAction());
749 TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgressAndAnotherCommitRequested)
751 StateMachine state;
752 state.setCanBeginFrame(true);
753 state.setVisible(true);
754 state.setCanDraw(true);
756 // Get a commit in flight.
757 state.setNeedsCommit(true);
758 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
759 state.updateState(state.nextAction());
761 // Set damage and expect a draw.
762 state.setNeedsRedraw(true);
763 state.didEnterVSync();
764 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
765 state.updateState(state.nextAction());
766 state.didLeaveVSync();
768 // Cause a lost context while the begin frame is in flight.
769 state.didLoseContext();
771 // Ask for another draw and also set needs commit. Expect nothing happens.
772 state.setNeedsRedraw(true);
773 state.setNeedsCommit(true);
774 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
776 // Finish the frame, and commit.
777 state.beginFrameComplete();
778 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
779 state.updateState(state.nextAction());
781 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, state.commitState());
783 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
784 state.updateState(state.nextAction());
786 // Expect to be told to begin context recreation, independent of vsync state
787 state.didEnterVSync();
788 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_CONTEXT_RECREATION, state.nextAction());
789 state.didLeaveVSync();
790 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_CONTEXT_RECREATION, state.nextAction());
794 TEST(SchedulerStateMachineTest, TestFinishAllRenderingWhileContextLost)
796 StateMachine state;
797 state.setVisible(true);
798 state.setCanDraw(true);
800 // Cause a lost context lost.
801 state.didLoseContext();
803 // Ask a forced redraw and verify it ocurrs.
804 state.setNeedsForcedRedraw(true);
805 state.didEnterVSync();
806 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.nextAction());
807 state.didLeaveVSync();
809 // Clear the forced redraw bit.
810 state.setNeedsForcedRedraw(false);
812 // Expect to be told to begin context recreation, independent of vsync state
813 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_CONTEXT_RECREATION, state.nextAction());
814 state.updateState(state.nextAction());
816 // Ask a forced redraw and verify it ocurrs.
817 state.setNeedsForcedRedraw(true);
818 state.didEnterVSync();
819 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.nextAction());
820 state.didLeaveVSync();
823 TEST(SchedulerStateMachineTest, TestBeginFrameWhenInvisibleAndForceCommit)
825 StateMachine state;
826 state.setCanBeginFrame(true);
827 state.setVisible(false);
828 state.setNeedsCommit(true);
829 state.setNeedsForcedCommit(true);
830 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
833 TEST(SchedulerStateMachineTest, TestBeginFrameWhenCanBeginFrameFalseAndForceCommit)
835 StateMachine state;
836 state.setVisible(true);
837 state.setCanDraw(true);
838 state.setNeedsCommit(true);
839 state.setNeedsForcedCommit(true);
840 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
843 TEST(SchedulerStateMachineTest, TestBeginFrameWhenCommitInProgress)
845 StateMachine state;
846 state.setCanBeginFrame(true);
847 state.setVisible(false);
848 state.setCommitState(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS);
849 state.setNeedsCommit(true);
850 state.setNeedsForcedCommit(true);
852 state.beginFrameComplete();
853 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
854 state.updateState(state.nextAction());
856 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, state.commitState());
858 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
861 TEST(SchedulerStateMachineTest, TestBeginFrameWhenContextLost)
863 StateMachine state;
864 state.setCanBeginFrame(true);
865 state.setVisible(true);
866 state.setCanDraw(true);
867 state.setNeedsCommit(true);
868 state.setNeedsForcedCommit(true);
869 state.didLoseContext();
870 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
873 } // anonymous namespace