Revert "Merged all Chromoting Host code into remoting_core.dll (Windows)."
[chromium-blink-merge.git] / cc / scheduler_state_machine_unittest.cc
blob686543c50e1253deee26b0777a51baffcdd9f3f2
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_state_machine.h"
7 #include "cc/scheduler.h"
8 #include "testing/gtest/include/gtest/gtest.h"
10 namespace cc {
12 namespace {
14 const SchedulerStateMachine::CommitState allCommitStates[] = {
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 StateMachine(const SchedulerSettings& schedulerSettings)
25 : SchedulerStateMachine(schedulerSettings) { }
26 void setCommitState(CommitState cs) { m_commitState = cs; }
27 CommitState commitState() const { return m_commitState; }
29 bool needsCommit() const { return m_needsCommit; }
31 void setNeedsRedraw(bool b) { m_needsRedraw = b; }
32 bool needsRedraw() const { return m_needsRedraw; }
34 void setNeedsForcedRedraw(bool b) { m_needsForcedRedraw = b; }
35 bool needsForcedRedraw() const { return m_needsForcedRedraw; }
37 bool canDraw() const { return m_canDraw; }
38 bool insideVSync() const { return m_insideVSync; }
39 bool visible() const { return m_visible; }
42 TEST(SchedulerStateMachineTest, TestNextActionBeginsFrameIfNeeded)
44 SchedulerSettings defaultSchedulerSettings;
46 // If no commit needed, do nothing
48 StateMachine state(defaultSchedulerSettings);
49 state.setCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
50 state.setCanBeginFrame(true);
51 state.setNeedsRedraw(false);
52 state.setVisible(true);
54 EXPECT_FALSE(state.vsyncCallbackNeeded());
56 state.didLeaveVSync();
57 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
58 EXPECT_FALSE(state.vsyncCallbackNeeded());
59 state.didEnterVSync();
60 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
63 // If commit requested but canBeginFrame is still false, do nothing.
65 StateMachine state(defaultSchedulerSettings);
66 state.setCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
67 state.setNeedsRedraw(false);
68 state.setVisible(true);
70 EXPECT_FALSE(state.vsyncCallbackNeeded());
72 state.didLeaveVSync();
73 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
74 EXPECT_FALSE(state.vsyncCallbackNeeded());
75 state.didEnterVSync();
76 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
80 // If commit requested, begin a frame
82 StateMachine state(defaultSchedulerSettings);
83 state.setCommitState(SchedulerStateMachine::COMMIT_STATE_IDLE);
84 state.setCanBeginFrame(true);
85 state.setNeedsRedraw(false);
86 state.setVisible(true);
87 EXPECT_FALSE(state.vsyncCallbackNeeded());
90 // Begin the frame, make sure needsCommit and commitState update correctly.
92 StateMachine state(defaultSchedulerSettings);
93 state.setCanBeginFrame(true);
94 state.setVisible(true);
95 state.updateState(SchedulerStateMachine::ACTION_BEGIN_FRAME);
96 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState());
97 EXPECT_FALSE(state.needsCommit());
98 EXPECT_FALSE(state.vsyncCallbackNeeded());
102 TEST(SchedulerStateMachineTest, TestSetForcedRedrawDoesNotSetsNormalRedraw)
104 SchedulerSettings defaultSchedulerSettings;
105 SchedulerStateMachine state(defaultSchedulerSettings);
106 state.setCanDraw(true);
107 state.setNeedsForcedRedraw();
108 EXPECT_FALSE(state.redrawPending());
109 EXPECT_TRUE(state.vsyncCallbackNeeded());
112 TEST(SchedulerStateMachineTest, TestFailedDrawSetsNeedsCommitAndDoesNotDrawAgain)
114 SchedulerSettings defaultSchedulerSettings;
115 SchedulerStateMachine state(defaultSchedulerSettings);
116 state.setCanBeginFrame(true);
117 state.setVisible(true);
118 state.setCanDraw(true);
119 state.setNeedsRedraw();
120 EXPECT_TRUE(state.redrawPending());
121 EXPECT_TRUE(state.vsyncCallbackNeeded());
122 state.didEnterVSync();
124 // We're drawing now.
125 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
126 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
127 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
128 EXPECT_FALSE(state.redrawPending());
129 EXPECT_FALSE(state.commitPending());
131 // Failing the draw makes us require a commit.
132 state.didDrawIfPossibleCompleted(false);
133 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
134 state.updateState(SchedulerStateMachine::ACTION_BEGIN_FRAME);
135 EXPECT_TRUE(state.redrawPending());
136 EXPECT_TRUE(state.commitPending());
139 TEST(SchedulerStateMachineTest, TestSetNeedsRedrawDuringFailedDrawDoesNotRemoveNeedsRedraw)
141 SchedulerSettings defaultSchedulerSettings;
142 SchedulerStateMachine state(defaultSchedulerSettings);
143 state.setCanBeginFrame(true);
144 state.setVisible(true);
145 state.setCanDraw(true);
146 state.setNeedsRedraw();
147 EXPECT_TRUE(state.redrawPending());
148 EXPECT_TRUE(state.vsyncCallbackNeeded());
149 state.didEnterVSync();
151 // We're drawing now.
152 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
153 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
154 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
155 EXPECT_FALSE(state.redrawPending());
156 EXPECT_FALSE(state.commitPending());
158 // While still in the same vsync callback, set needs redraw again.
159 // This should not redraw.
160 state.setNeedsRedraw();
161 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
163 // Failing the draw makes us require a commit.
164 state.didDrawIfPossibleCompleted(false);
165 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
166 EXPECT_TRUE(state.redrawPending());
169 TEST(SchedulerStateMachineTest, TestCommitAfterFailedDrawAllowsDrawInSameFrame)
171 SchedulerSettings defaultSchedulerSettings;
172 SchedulerStateMachine state(defaultSchedulerSettings);
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 SchedulerSettings defaultSchedulerSettings;
211 SchedulerStateMachine state(defaultSchedulerSettings);
212 state.setCanBeginFrame(true);
213 state.setVisible(true);
214 state.setCanDraw(true);
216 // Start a commit.
217 state.setNeedsCommit();
218 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
219 state.updateState(SchedulerStateMachine::ACTION_BEGIN_FRAME);
220 EXPECT_TRUE(state.commitPending());
222 // Then initiate a draw.
223 state.setNeedsRedraw();
224 EXPECT_TRUE(state.vsyncCallbackNeeded());
225 state.didEnterVSync();
226 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
227 EXPECT_TRUE(state.redrawPending());
229 // Fail the draw.
230 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
231 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
232 state.didDrawIfPossibleCompleted(false);
233 EXPECT_TRUE(state.redrawPending());
234 // But the commit is ongoing.
235 EXPECT_TRUE(state.commitPending());
237 // Force a draw.
238 state.setNeedsForcedRedraw();
239 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.nextAction());
241 // Do the forced draw.
242 state.updateState(SchedulerStateMachine::ACTION_DRAW_FORCED);
243 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
244 EXPECT_FALSE(state.redrawPending());
245 // And the commit is still ongoing.
246 EXPECT_TRUE(state.commitPending());
248 // Finish the commit.
249 state.beginFrameComplete();
250 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
251 state.updateState(SchedulerStateMachine::ACTION_COMMIT);
252 EXPECT_TRUE(state.redrawPending());
254 // And we should not be allowed to draw again in the same frame..
255 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
258 TEST(SchedulerStateMachineTest, TestFailedDrawsWillEventuallyForceADrawAfterTheNextCommit)
260 SchedulerSettings defaultSchedulerSettings;
261 SchedulerStateMachine state(defaultSchedulerSettings);
262 state.setCanBeginFrame(true);
263 state.setVisible(true);
264 state.setCanDraw(true);
265 state.setMaximumNumberOfFailedDrawsBeforeDrawIsForced(1);
267 // Start a commit.
268 state.setNeedsCommit();
269 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
270 state.updateState(SchedulerStateMachine::ACTION_BEGIN_FRAME);
271 EXPECT_TRUE(state.commitPending());
273 // Then initiate a draw.
274 state.setNeedsRedraw();
275 EXPECT_TRUE(state.vsyncCallbackNeeded());
276 state.didEnterVSync();
277 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
278 EXPECT_TRUE(state.redrawPending());
280 // Fail the draw.
281 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
282 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
283 state.didDrawIfPossibleCompleted(false);
284 EXPECT_TRUE(state.redrawPending());
285 // But the commit is ongoing.
286 EXPECT_TRUE(state.commitPending());
288 // Finish the commit. Note, we should not yet be forcing a draw, but should
289 // continue the commit as usual.
290 state.beginFrameComplete();
291 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
292 state.updateState(SchedulerStateMachine::ACTION_COMMIT);
293 EXPECT_TRUE(state.redrawPending());
295 // The redraw should be forced in this case.
296 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.nextAction());
299 TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedNextVSync)
301 SchedulerSettings defaultSchedulerSettings;
302 SchedulerStateMachine state(defaultSchedulerSettings);
303 state.setCanBeginFrame(true);
304 state.setVisible(true);
305 state.setCanDraw(true);
307 // Start a draw.
308 state.setNeedsRedraw();
309 EXPECT_TRUE(state.vsyncCallbackNeeded());
310 state.didEnterVSync();
311 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
312 EXPECT_TRUE(state.redrawPending());
314 // Fail the draw.
315 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
316 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
317 state.didDrawIfPossibleCompleted(false);
318 EXPECT_TRUE(state.redrawPending());
320 // We should not be trying to draw again now, but we have a commit pending.
321 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
323 state.didLeaveVSync();
324 EXPECT_TRUE(state.vsyncCallbackNeeded());
325 state.didEnterVSync();
327 // We should try draw again in the next vsync.
328 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
331 TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame)
333 SchedulerSettings defaultSchedulerSettings;
334 SchedulerStateMachine state(defaultSchedulerSettings);
335 state.setVisible(true);
336 state.setCanDraw(true);
337 state.setNeedsRedraw();
338 EXPECT_TRUE(state.vsyncCallbackNeeded());
339 state.didEnterVSync();
340 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
341 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
343 // While still in the same vsync callback, set needs redraw again.
344 // This should not redraw.
345 state.setNeedsRedraw();
346 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
348 // Move to another frame. This should now draw.
349 state.didDrawIfPossibleCompleted(true);
350 state.didLeaveVSync();
351 EXPECT_TRUE(state.vsyncCallbackNeeded());
352 state.didEnterVSync();
354 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
355 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
356 state.didDrawIfPossibleCompleted(true);
357 EXPECT_FALSE(state.vsyncCallbackNeeded());
360 TEST(SchedulerStateMachineTest, TestNextActionDrawsOnVSync)
362 SchedulerSettings defaultSchedulerSettings;
364 // When not on vsync, or on vsync but not visible, don't draw.
365 size_t numCommitStates = sizeof(allCommitStates) / sizeof(SchedulerStateMachine::CommitState);
366 for (size_t i = 0; i < numCommitStates; ++i) {
367 for (unsigned j = 0; j < 2; ++j) {
368 StateMachine state(defaultSchedulerSettings);
369 state.setCommitState(allCommitStates[i]);
370 bool visible = j;
371 if (!visible) {
372 state.didEnterVSync();
373 state.setVisible(false);
374 } else
375 state.setVisible(true);
377 // Case 1: needsCommit=false
378 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
380 // Case 2: needsCommit=true
381 state.setNeedsCommit();
382 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
386 // When on vsync, or not on vsync but needsForcedRedraw set, should always draw except if you're ready to commit, in which case commit.
387 for (size_t i = 0; i < numCommitStates; ++i) {
388 for (unsigned j = 0; j < 2; ++j) {
389 StateMachine state(defaultSchedulerSettings);
390 state.setCanDraw(true);
391 state.setCommitState(allCommitStates[i]);
392 bool forcedDraw = j;
393 if (!forcedDraw) {
394 state.didEnterVSync();
395 state.setNeedsRedraw(true);
396 state.setVisible(true);
397 } else
398 state.setNeedsForcedRedraw(true);
400 SchedulerStateMachine::Action expectedAction;
401 if (allCommitStates[i] != SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT)
402 expectedAction = forcedDraw ? SchedulerStateMachine::ACTION_DRAW_FORCED : SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE;
403 else
404 expectedAction = SchedulerStateMachine::ACTION_COMMIT;
406 // Case 1: needsCommit=false.
407 EXPECT_TRUE(state.vsyncCallbackNeeded());
408 EXPECT_EQ(expectedAction, state.nextAction());
410 // Case 2: needsCommit=true.
411 state.setNeedsCommit();
412 EXPECT_TRUE(state.vsyncCallbackNeeded());
413 EXPECT_EQ(expectedAction, state.nextAction());
418 TEST(SchedulerStateMachineTest, TestNoCommitStatesRedrawWhenInvisible)
420 SchedulerSettings defaultSchedulerSettings;
422 size_t numCommitStates = sizeof(allCommitStates) / sizeof(SchedulerStateMachine::CommitState);
423 for (size_t i = 0; i < numCommitStates; ++i) {
424 // There shouldn't be any drawing regardless of vsync.
425 for (unsigned j = 0; j < 2; ++j) {
426 StateMachine state(defaultSchedulerSettings);
427 state.setCommitState(allCommitStates[i]);
428 state.setVisible(false);
429 state.setNeedsRedraw(true);
430 state.setNeedsForcedRedraw(false);
431 if (j == 1)
432 state.didEnterVSync();
434 // Case 1: needsCommit=false.
435 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
437 // Case 2: needsCommit=true.
438 state.setNeedsCommit();
439 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
444 TEST(SchedulerStateMachineTest, TestCanRedraw_StopsDraw)
446 SchedulerSettings defaultSchedulerSettings;
448 size_t numCommitStates = sizeof(allCommitStates) / sizeof(SchedulerStateMachine::CommitState);
449 for (size_t i = 0; i < numCommitStates; ++i) {
450 // There shouldn't be any drawing regardless of vsync.
451 for (unsigned j = 0; j < 2; ++j) {
452 StateMachine state(defaultSchedulerSettings);
453 state.setCommitState(allCommitStates[i]);
454 state.setVisible(false);
455 state.setNeedsRedraw(true);
456 state.setNeedsForcedRedraw(false);
457 if (j == 1)
458 state.didEnterVSync();
460 state.setCanDraw(false);
461 EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
466 TEST(SchedulerStateMachineTest, TestCanRedrawWithWaitingForFirstDrawMakesProgress)
468 SchedulerSettings defaultSchedulerSettings;
469 StateMachine state(defaultSchedulerSettings);
470 state.setCommitState(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW);
471 state.setCanBeginFrame(true);
472 state.setNeedsCommit();
473 state.setNeedsRedraw(true);
474 state.setVisible(true);
475 state.setCanDraw(false);
476 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
479 TEST(SchedulerStateMachineTest, TestSetNeedsCommitIsNotLost)
481 SchedulerSettings defaultSchedulerSettings;
482 StateMachine state(defaultSchedulerSettings);
483 state.setCanBeginFrame(true);
484 state.setNeedsCommit();
485 state.setVisible(true);
486 state.setCanDraw(true);
488 // Begin the frame.
489 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
490 state.updateState(state.nextAction());
491 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState());
493 // Now, while the frame is in progress, set another commit.
494 state.setNeedsCommit();
495 EXPECT_TRUE(state.needsCommit());
497 // Let the frame finish.
498 state.beginFrameComplete();
499 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, state.commitState());
501 // Expect to commit regardless of vsync state.
502 state.didLeaveVSync();
503 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
504 state.didEnterVSync();
505 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
507 // Commit and make sure we draw on next vsync
508 state.updateState(SchedulerStateMachine::ACTION_COMMIT);
509 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
510 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, state.commitState());
511 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
512 state.didDrawIfPossibleCompleted(true);
514 // Verify that another commit will begin.
515 state.didLeaveVSync();
516 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
519 TEST(SchedulerStateMachineTest, TestFullCycle)
521 SchedulerSettings defaultSchedulerSettings;
522 StateMachine state(defaultSchedulerSettings);
523 state.setCanBeginFrame(true);
524 state.setVisible(true);
525 state.setCanDraw(true);
527 // Start clean and set commit.
528 state.setNeedsCommit();
529 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
531 // Begin the frame.
532 state.updateState(SchedulerStateMachine::ACTION_BEGIN_FRAME);
533 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState());
534 EXPECT_FALSE(state.needsCommit());
535 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
537 // Tell the scheduler the frame finished.
538 state.beginFrameComplete();
539 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, state.commitState());
540 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
542 // Commit.
543 state.updateState(SchedulerStateMachine::ACTION_COMMIT);
544 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, state.commitState());
545 EXPECT_TRUE(state.needsRedraw());
547 // Expect to do nothing until vsync.
548 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
550 // At vsync, draw.
551 state.didEnterVSync();
552 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
553 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
554 state.didDrawIfPossibleCompleted(true);
555 state.didLeaveVSync();
557 // Should be synchronized, no draw needed, no action needed.
558 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.commitState());
559 EXPECT_FALSE(state.needsRedraw());
560 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
563 TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween)
565 SchedulerSettings defaultSchedulerSettings;
566 StateMachine state(defaultSchedulerSettings);
567 state.setCanBeginFrame(true);
568 state.setVisible(true);
569 state.setCanDraw(true);
571 // Start clean and set commit.
572 state.setNeedsCommit();
573 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
575 // Begin the frame.
576 state.updateState(SchedulerStateMachine::ACTION_BEGIN_FRAME);
577 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState());
578 EXPECT_FALSE(state.needsCommit());
579 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
581 // Request another commit while the commit is in flight.
582 state.setNeedsCommit();
583 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
585 // Tell the scheduler the frame finished.
586 state.beginFrameComplete();
587 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, state.commitState());
588 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
590 // Commit.
591 state.updateState(SchedulerStateMachine::ACTION_COMMIT);
592 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, state.commitState());
593 EXPECT_TRUE(state.needsRedraw());
595 // Expect to do nothing until vsync.
596 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
598 // At vsync, draw.
599 state.didEnterVSync();
600 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
601 state.updateState(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
602 state.didDrawIfPossibleCompleted(true);
603 state.didLeaveVSync();
605 // Should be synchronized, no draw needed, no action needed.
606 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.commitState());
607 EXPECT_FALSE(state.needsRedraw());
608 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
611 TEST(SchedulerStateMachineTest, TestRequestCommitInvisible)
613 SchedulerSettings defaultSchedulerSettings;
614 StateMachine state(defaultSchedulerSettings);
615 state.setNeedsCommit();
616 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
619 TEST(SchedulerStateMachineTest, TestGoesInvisibleBeforeBeginFrameCompletes)
621 SchedulerSettings defaultSchedulerSettings;
622 StateMachine state(defaultSchedulerSettings);
623 state.setCanBeginFrame(true);
624 state.setVisible(true);
625 state.setCanDraw(true);
627 // Start clean and set commit.
628 state.setNeedsCommit();
629 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
631 // Begin the frame while visible.
632 state.updateState(SchedulerStateMachine::ACTION_BEGIN_FRAME);
633 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState());
634 EXPECT_FALSE(state.needsCommit());
635 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
637 // Become invisible and abort the beginFrame.
638 state.setVisible(false);
639 state.beginFrameAborted();
641 // We should now be back in the idle state as if we didn't start a frame at all.
642 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.commitState());
643 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
645 // Become visible again
646 state.setVisible(true);
648 // We should be beginning a frame now
649 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.commitState());
650 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
652 // Begin the frame
653 state.updateState(state.nextAction());
655 // We should be starting the commit now
656 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState());
659 TEST(SchedulerStateMachineTest, TestContextLostWhenCompletelyIdle)
661 SchedulerSettings defaultSchedulerSettings;
662 StateMachine state(defaultSchedulerSettings);
663 state.setCanBeginFrame(true);
664 state.setVisible(true);
665 state.setCanDraw(true);
667 state.didLoseOutputSurface();
669 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_RECREATION, state.nextAction());
670 state.updateState(state.nextAction());
672 // Once context recreation begins, nothing should happen.
673 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
675 // Recreate the context
676 state.didRecreateOutputSurface();
678 // When the context is recreated, we should begin a commit
679 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
680 state.updateState(state.nextAction());
683 TEST(SchedulerStateMachineTest, TestContextLostWhenIdleAndCommitRequestedWhileRecreating)
685 SchedulerSettings defaultSchedulerSettings;
686 StateMachine state(defaultSchedulerSettings);
687 state.setCanBeginFrame(true);
688 state.setVisible(true);
689 state.setCanDraw(true);
691 state.didLoseOutputSurface();
693 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_RECREATION, state.nextAction());
694 state.updateState(state.nextAction());
696 // Once context recreation begins, nothing should happen.
697 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
699 // While context is recreating, commits shouldn't begin.
700 state.setNeedsCommit();
701 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
703 // Recreate the context
704 state.didRecreateOutputSurface();
706 // When the context is recreated, we should begin a commit
707 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
708 state.updateState(state.nextAction());
710 // Once the context is recreated, whether we draw should be based on
711 // setCanDraw.
712 state.setNeedsRedraw(true);
713 state.didEnterVSync();
714 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
715 state.setCanDraw(false);
716 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
717 state.setCanDraw(true);
718 state.didLeaveVSync();
721 TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress)
723 SchedulerSettings defaultSchedulerSettings;
724 StateMachine state(defaultSchedulerSettings);
725 state.setCanBeginFrame(true);
726 state.setVisible(true);
727 state.setCanDraw(true);
729 // Get a commit in flight.
730 state.setNeedsCommit();
731 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
732 state.updateState(state.nextAction());
734 // Set damage and expect a draw.
735 state.setNeedsRedraw(true);
736 state.didEnterVSync();
737 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
738 state.updateState(state.nextAction());
739 state.didLeaveVSync();
741 // Cause a lost context while the begin frame is in flight.
742 state.didLoseOutputSurface();
744 // Ask for another draw. Expect nothing happens.
745 state.setNeedsRedraw(true);
746 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
748 // Finish the frame, and commit.
749 state.beginFrameComplete();
750 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
751 state.updateState(state.nextAction());
753 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, state.commitState());
755 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
756 state.updateState(state.nextAction());
758 // Expect to be told to begin context recreation, independent of vsync state
759 state.didEnterVSync();
760 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_RECREATION, state.nextAction());
761 state.didLeaveVSync();
762 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_RECREATION, state.nextAction());
765 TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgressAndAnotherCommitRequested)
767 SchedulerSettings defaultSchedulerSettings;
768 StateMachine state(defaultSchedulerSettings);
769 state.setCanBeginFrame(true);
770 state.setVisible(true);
771 state.setCanDraw(true);
773 // Get a commit in flight.
774 state.setNeedsCommit();
775 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
776 state.updateState(state.nextAction());
778 // Set damage and expect a draw.
779 state.setNeedsRedraw(true);
780 state.didEnterVSync();
781 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
782 state.updateState(state.nextAction());
783 state.didLeaveVSync();
785 // Cause a lost context while the begin frame is in flight.
786 state.didLoseOutputSurface();
788 // Ask for another draw and also set needs commit. Expect nothing happens.
789 state.setNeedsRedraw(true);
790 state.setNeedsCommit();
791 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
793 // Finish the frame, and commit.
794 state.beginFrameComplete();
795 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
796 state.updateState(state.nextAction());
798 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, state.commitState());
800 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.nextAction());
801 state.updateState(state.nextAction());
803 // Expect to be told to begin context recreation, independent of vsync state
804 state.didEnterVSync();
805 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_RECREATION, state.nextAction());
806 state.didLeaveVSync();
807 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_RECREATION, state.nextAction());
811 TEST(SchedulerStateMachineTest, TestFinishAllRenderingWhileContextLost)
813 SchedulerSettings defaultSchedulerSettings;
814 StateMachine state(defaultSchedulerSettings);
815 state.setVisible(true);
816 state.setCanDraw(true);
818 // Cause a lost context lost.
819 state.didLoseOutputSurface();
821 // Ask a forced redraw and verify it ocurrs.
822 state.setNeedsForcedRedraw(true);
823 state.didEnterVSync();
824 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.nextAction());
825 state.didLeaveVSync();
827 // Clear the forced redraw bit.
828 state.setNeedsForcedRedraw(false);
830 // Expect to be told to begin context recreation, independent of vsync state
831 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_RECREATION, state.nextAction());
832 state.updateState(state.nextAction());
834 // Ask a forced redraw and verify it ocurrs.
835 state.setNeedsForcedRedraw(true);
836 state.didEnterVSync();
837 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.nextAction());
838 state.didLeaveVSync();
841 TEST(SchedulerStateMachineTest, TestBeginFrameWhenInvisibleAndForceCommit)
843 SchedulerSettings defaultSchedulerSettings;
844 StateMachine state(defaultSchedulerSettings);
845 state.setCanBeginFrame(true);
846 state.setVisible(false);
847 state.setNeedsCommit();
848 state.setNeedsForcedCommit();
849 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
852 TEST(SchedulerStateMachineTest, TestBeginFrameWhenCanBeginFrameFalseAndForceCommit)
854 SchedulerSettings defaultSchedulerSettings;
855 StateMachine state(defaultSchedulerSettings);
856 state.setVisible(true);
857 state.setCanDraw(true);
858 state.setNeedsCommit();
859 state.setNeedsForcedCommit();
860 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
863 TEST(SchedulerStateMachineTest, TestBeginFrameWhenCommitInProgress)
865 SchedulerSettings defaultSchedulerSettings;
866 StateMachine state(defaultSchedulerSettings);
867 state.setCanBeginFrame(true);
868 state.setVisible(false);
869 state.setCommitState(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS);
870 state.setNeedsCommit();
872 state.beginFrameComplete();
873 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
874 state.updateState(state.nextAction());
876 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, state.commitState());
878 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
881 TEST(SchedulerStateMachineTest, TestBeginFrameWhenForcedCommitInProgress)
883 SchedulerSettings defaultSchedulerSettings;
884 StateMachine state(defaultSchedulerSettings);
885 state.setCanBeginFrame(true);
886 state.setVisible(false);
887 state.setCommitState(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS);
888 state.setNeedsCommit();
889 state.setNeedsForcedCommit();
891 state.beginFrameComplete();
892 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
893 state.updateState(state.nextAction());
895 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW, state.commitState());
897 // If we are waiting for forced draw then we know a begin frame is already in flight.
898 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
901 TEST(SchedulerStateMachineTest, TestBeginFrameWhenContextLost)
903 SchedulerSettings defaultSchedulerSettings;
904 StateMachine state(defaultSchedulerSettings);
905 state.setCanBeginFrame(true);
906 state.setVisible(true);
907 state.setCanDraw(true);
908 state.setNeedsCommit();
909 state.setNeedsForcedCommit();
910 state.didLoseOutputSurface();
911 EXPECT_EQ(SchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
914 TEST(SchedulerStateMachineTest, TestImmediateBeginFrame)
916 SchedulerSettings defaultSchedulerSettings;
917 StateMachine state(defaultSchedulerSettings);
918 state.setCanBeginFrame(true);
919 state.setVisible(true);
920 state.setCanDraw(true);
922 // Schedule a forced frame, commit it, draw it.
923 state.setNeedsCommit();
924 state.setNeedsForcedCommit();
925 state.updateState(state.nextAction());
926 state.beginFrameComplete();
927 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
928 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, state.commitState());
929 state.updateState(state.nextAction());
931 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW, state.commitState());
933 state.didEnterVSync();
934 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
935 state.setNeedsForcedRedraw(true);
936 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.nextAction());
937 state.updateState(state.nextAction());
938 state.didDrawIfPossibleCompleted(true);
939 state.didLeaveVSync();
941 // Should be waiting for the normal begin frame
942 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState());
945 TEST(SchedulerStateMachineTest, TestImmediateBeginFrameDuringCommit)
947 SchedulerSettings defaultSchedulerSettings;
948 StateMachine state(defaultSchedulerSettings);
949 state.setCanBeginFrame(true);
950 state.setVisible(true);
951 state.setCanDraw(true);
953 // Start a normal commit.
954 state.setNeedsCommit();
955 state.updateState(state.nextAction());
957 // Schedule a forced frame, commit it, draw it.
958 state.setNeedsCommit();
959 state.setNeedsForcedCommit();
960 state.updateState(state.nextAction());
961 state.beginFrameComplete();
962 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
963 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, state.commitState());
964 state.updateState(state.nextAction());
966 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW, state.commitState());
968 state.didEnterVSync();
969 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
970 state.setNeedsForcedRedraw(true);
971 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.nextAction());
972 state.updateState(state.nextAction());
973 state.didDrawIfPossibleCompleted(true);
974 state.didLeaveVSync();
976 // Should be waiting for the normal begin frame
977 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState()) << state.toString();
980 TEST(SchedulerStateMachineTest, ImmediateBeginFrameWhileInvisible)
982 SchedulerSettings defaultSchedulerSettings;
983 StateMachine state(defaultSchedulerSettings);
984 state.setCanBeginFrame(true);
985 state.setVisible(true);
986 state.setCanDraw(true);
988 state.setNeedsCommit();
989 state.updateState(state.nextAction());
991 state.setNeedsCommit();
992 state.setNeedsForcedCommit();
993 state.updateState(state.nextAction());
994 state.beginFrameComplete();
996 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
997 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, state.commitState());
998 state.updateState(state.nextAction());
1000 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW, state.commitState());
1002 state.didEnterVSync();
1003 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
1004 state.setNeedsForcedRedraw(true);
1005 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.nextAction());
1006 state.updateState(state.nextAction());
1007 state.didDrawIfPossibleCompleted(true);
1008 state.didLeaveVSync();
1010 // Should be waiting for the normal begin frame
1011 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState()) << state.toString();
1014 // Become invisible and abort the "normal" begin frame.
1015 state.setVisible(false);
1016 state.beginFrameAborted();
1018 // Should be back in the idle state, but needing a commit.
1019 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_IDLE, state.commitState());
1020 EXPECT_TRUE(state.needsCommit());
1023 TEST(SchedulerStateMachineTest, ImmediateBeginFrameWhileCantDraw)
1025 SchedulerSettings defaultSchedulerSettings;
1026 StateMachine state(defaultSchedulerSettings);
1027 state.setCanBeginFrame(true);
1028 state.setVisible(true);
1029 state.setCanDraw(false);
1031 state.setNeedsCommit();
1032 state.updateState(state.nextAction());
1034 state.setNeedsCommit();
1035 state.setNeedsForcedCommit();
1036 state.updateState(state.nextAction());
1037 state.beginFrameComplete();
1039 EXPECT_EQ(SchedulerStateMachine::ACTION_COMMIT, state.nextAction());
1040 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, state.commitState());
1041 state.updateState(state.nextAction());
1043 EXPECT_EQ(SchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_FORCED_DRAW, state.commitState());
1045 state.didEnterVSync();
1046 EXPECT_EQ(SchedulerStateMachine::ACTION_NONE, state.nextAction());
1047 state.setNeedsForcedRedraw(true);
1048 EXPECT_EQ(SchedulerStateMachine::ACTION_DRAW_FORCED, state.nextAction());
1049 state.updateState(state.nextAction());
1050 state.didDrawIfPossibleCompleted(true);
1051 state.didLeaveVSync();
1054 } // namespace
1055 } // namespace cc