tizen beta release
[profile/ivi/webkit-efl.git] / Source / WebKit / chromium / tests / CCSchedulerStateMachineTest.cpp
1 /*
2  * Copyright (C) 2011 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1.  Redistributions of source code must retain the above copyright
8  *     notice, this list of conditions and the following disclaimer.
9  * 2.  Redistributions in binary form must reproduce the above copyright
10  *     notice, this list of conditions and the following disclaimer in the
11  *     documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23  */
24
25 #include "config.h"
26
27 #include "cc/CCSchedulerStateMachine.h"
28
29 #include <gtest/gtest.h>
30 #include <wtf/text/CString.h>
31 #include <wtf/text/WTFString.h>
32
33 using namespace WTF;
34 using namespace WebCore;
35
36 namespace {
37
38 const CCSchedulerStateMachine::CommitState allCommitStates[] = {
39     CCSchedulerStateMachine::COMMIT_STATE_IDLE,
40     CCSchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS,
41     CCSchedulerStateMachine::COMMIT_STATE_UPDATING_RESOURCES,
42     CCSchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT,
43     CCSchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW
44 };
45
46 // Exposes the protected state fields of the CCSchedulerStateMachine for testing
47 class StateMachine : public CCSchedulerStateMachine {
48 public:
49     void setCommitState(CommitState cs) { m_commitState = cs; }
50     CommitState commitState() const { return  m_commitState; }
51
52     void setNeedsCommit(bool b) { m_needsCommit = b; }
53     bool needsCommit() const { return m_needsCommit; }
54
55     void setNeedsRedraw(bool b) { m_needsRedraw = b; }
56     bool needsRedraw() const { return m_needsRedraw; }
57
58     void setNeedsForcedRedraw(bool b) { m_needsForcedRedraw = b; }
59     bool needsForcedRedraw() const { return m_needsForcedRedraw; }
60
61     bool insideVSync() const { return m_insideVSync; }
62     bool visible() const { return m_visible; }
63
64     void setUpdateMoreResourcesPending(bool b) { m_updateMoreResourcesPending = b; }
65     bool updateMoreResourcesPending() const { return m_updateMoreResourcesPending; }
66 };
67
68 TEST(CCSchedulerStateMachineTest, TestNextActionBeginsFrameIfNeeded)
69 {
70     // If no commit needed, do nothing
71     {
72         StateMachine state;
73         state.setCommitState(CCSchedulerStateMachine::COMMIT_STATE_IDLE);
74         state.setNeedsRedraw(false);
75         state.setNeedsCommit(false);
76         state.setUpdateMoreResourcesPending(false);
77         state.setVisible(true);
78
79         state.didLeaveVSync();
80         EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
81         state.didEnterVSync();
82         EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
83     }
84
85     // If commit requested, begin a frame
86     {
87         StateMachine state;
88         state.setCommitState(CCSchedulerStateMachine::COMMIT_STATE_IDLE);
89         state.setNeedsRedraw(false);
90         state.setNeedsCommit(true);
91         state.setUpdateMoreResourcesPending(false);
92         state.setVisible(true);
93     }
94
95     // Begin the frame, make sure needsCommit and commitState update correctly.
96     {
97         StateMachine state;
98         state.setVisible(true);
99         state.updateState(CCSchedulerStateMachine::ACTION_BEGIN_FRAME);
100         EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState());
101         EXPECT_FALSE(state.needsCommit());
102     }
103 }
104
105 TEST(CCSchedulerStateMachineTest, TestSetForcedRedrawDoesNotSetsNormalRedraw)
106 {
107     CCSchedulerStateMachine state;
108     state.setNeedsForcedRedraw();
109     EXPECT_FALSE(state.redrawPending());
110 }
111
112 TEST(CCSchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame)
113 {
114     CCSchedulerStateMachine state;
115     state.setVisible(true);
116     state.setNeedsRedraw();
117     state.didEnterVSync();
118     EXPECT_EQ(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
119     state.updateState(CCSchedulerStateMachine::ACTION_DRAW);
120
121     // While still in the same vsync callback, set needs redraw again.
122     // This should not redraw.
123     state.setNeedsRedraw();
124     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
125
126     // Move to another frame. This should now draw.
127     state.didLeaveVSync();
128     state.didEnterVSync();
129
130     EXPECT_EQ(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
131     state.updateState(CCSchedulerStateMachine::ACTION_DRAW);
132 }
133
134 TEST(CCSchedulerStateMachineTest, TestNextActionDrawsOnVSync)
135 {
136     // When not on vsync, or on vsync but not visible, don't draw.
137     size_t numCommitStates = sizeof(allCommitStates) / sizeof(CCSchedulerStateMachine::CommitState);
138     for (size_t i = 0; i < numCommitStates; ++i) {
139         for (unsigned j = 0; j < 2; ++j) {
140             StateMachine state;
141             state.setCommitState(allCommitStates[i]);
142             if (!j) {
143                 state.didEnterVSync();
144                 state.setVisible(false);
145             }
146
147             // Case 1: needsCommit=false updateMoreResourcesPending=false.
148             state.setNeedsCommit(false);
149             state.setUpdateMoreResourcesPending(false);
150             EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
151
152             // Case 2: needsCommit=false updateMoreResourcesPending=true.
153             state.setNeedsCommit(false);
154             state.setUpdateMoreResourcesPending(true);
155             EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
156
157             // Case 3: needsCommit=true updateMoreResourcesPending=false.
158             state.setNeedsCommit(true);
159             state.setUpdateMoreResourcesPending(false);
160             EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
161
162             // Case 4: needsCommit=true updateMoreResourcesPending=true.
163             state.setNeedsCommit(true);
164             state.setUpdateMoreResourcesPending(true);
165             EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
166         }
167     }
168
169     // When on vsync, or not on vsync but needsForcedRedraw set, should always draw expect if you're ready to commit, in which case commit.
170     for (size_t i = 0; i < numCommitStates; ++i) {
171         for (unsigned j = 0; j < 2; ++j) {
172             StateMachine state;
173             state.setCommitState(allCommitStates[i]);
174             if (!j) {
175                 state.didEnterVSync();
176                 state.setNeedsRedraw(true);
177                 state.setVisible(true);
178             } else
179                 state.setNeedsForcedRedraw(true);
180
181             CCSchedulerStateMachine::Action expectedAction;
182             if (allCommitStates[i] != CCSchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT)
183                 expectedAction = CCSchedulerStateMachine::ACTION_DRAW;
184             else
185                 expectedAction = CCSchedulerStateMachine::ACTION_COMMIT;
186
187             // Case 1: needsCommit=false updateMoreResourcesPending=false.
188             state.setNeedsCommit(false);
189             state.setUpdateMoreResourcesPending(false);
190             EXPECT_EQ(expectedAction, state.nextAction());
191
192             // Case 2: needsCommit=false updateMoreResourcesPending=true.
193             state.setNeedsCommit(false);
194             state.setUpdateMoreResourcesPending(true);
195             EXPECT_EQ(expectedAction, state.nextAction());
196
197             // Case 3: needsCommit=true updateMoreResourcesPending=false.
198             state.setNeedsCommit(true);
199             state.setUpdateMoreResourcesPending(false);
200             EXPECT_EQ(expectedAction, state.nextAction());
201
202             // Case 4: needsCommit=true updateMoreResourcesPending=true.
203             state.setNeedsCommit(true);
204             state.setUpdateMoreResourcesPending(true);
205             EXPECT_EQ(expectedAction, state.nextAction());
206         }
207     }
208 }
209
210 TEST(CCSchedulerStateMachineTest, TestNoCommitStatesRedrawWhenInvisible)
211 {
212     size_t numCommitStates = sizeof(allCommitStates) / sizeof(CCSchedulerStateMachine::CommitState);
213     for (size_t i = 0; i < numCommitStates; ++i) {
214         // There shouldn't be any drawing regardless of vsync.
215         for (unsigned j = 0; j < 2; ++j) {
216             StateMachine state;
217             state.setCommitState(allCommitStates[i]);
218             state.setVisible(false);
219             state.setNeedsRedraw(true);
220             state.setNeedsForcedRedraw(false);
221             if (j == 1)
222                 state.didEnterVSync();
223
224             // Case 1: needsCommit=false updateMoreResourcesPending=false.
225             state.setNeedsCommit(false);
226             state.setUpdateMoreResourcesPending(false);
227             EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
228
229             // Case 2: needsCommit=false updateMoreResourcesPending=true.
230             state.setNeedsCommit(false);
231             state.setUpdateMoreResourcesPending(true);
232             EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
233
234             // Case 3: needsCommit=true updateMoreResourcesPending=false.
235             state.setNeedsCommit(true);
236             state.setUpdateMoreResourcesPending(false);
237             EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
238
239             // Case 4: needsCommit=true updateMoreResourcesPending=true.
240             state.setNeedsCommit(true);
241             state.setUpdateMoreResourcesPending(true);
242             EXPECT_NE(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
243         }
244     }
245 }
246
247 TEST(CCSchedulerStateMachineTest, TestUpdates_NoRedraw_OneRoundOfUpdates)
248 {
249     StateMachine state;
250     state.setCommitState(CCSchedulerStateMachine::COMMIT_STATE_UPDATING_RESOURCES);
251     state.setNeedsRedraw(false);
252     state.setUpdateMoreResourcesPending(false);
253     state.setVisible(true);
254
255     // Verify we begin update, both for vsync and not vsync.
256     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES, state.nextAction());
257     state.didEnterVSync();
258     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES, state.nextAction());
259
260     // Begin an update.
261     state.updateState(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES);
262
263     // Verify we don't do anything, both for vsync and not vsync.
264     state.didLeaveVSync();
265     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
266     state.didEnterVSync();
267     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
268
269     // End update with no more updates pending.
270     state.beginUpdateMoreResourcesComplete(false);
271     state.didLeaveVSync();
272     EXPECT_EQ(CCSchedulerStateMachine::ACTION_COMMIT, state.nextAction());
273 }
274
275 TEST(CCSchedulerStateMachineTest, TestUpdates_NoRedraw_TwoRoundsOfUpdates)
276 {
277     StateMachine state;
278     state.setCommitState(CCSchedulerStateMachine::COMMIT_STATE_UPDATING_RESOURCES);
279     state.setNeedsRedraw(false);
280     state.setUpdateMoreResourcesPending(false);
281     state.setVisible(true);
282
283     // Verify the update begins, both for vsync and not vsync.
284     state.didEnterVSync();
285     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES, state.nextAction());
286     state.didLeaveVSync();
287     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES, state.nextAction());
288
289     // Begin an update.
290     state.updateState(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES);
291
292     // Verify we do nothing, both for vsync and not vsync.
293     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
294     state.didEnterVSync();
295     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
296
297     // Ack the update with more pending.
298     state.beginUpdateMoreResourcesComplete(true);
299
300     // Verify we update more, both for vsync and not vsync.
301     state.didLeaveVSync();
302     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES, state.nextAction());
303     state.didEnterVSync();
304     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES, state.nextAction());
305
306     // Begin another update, while inside vsync. And, it updating.
307     state.updateState(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES);
308     state.beginUpdateMoreResourcesComplete(false);
309
310     // Make sure we commit, independent of vsync.
311     state.didLeaveVSync();
312     EXPECT_EQ(CCSchedulerStateMachine::ACTION_COMMIT, state.nextAction());
313     state.didEnterVSync();
314     EXPECT_EQ(CCSchedulerStateMachine::ACTION_COMMIT, state.nextAction());
315 }
316
317 TEST(CCSchedulerStateMachineTest, TestUpdates_WithRedraw_OneRoundOfUpdates)
318 {
319     StateMachine state;
320     state.setCommitState(CCSchedulerStateMachine::COMMIT_STATE_UPDATING_RESOURCES);
321     state.setNeedsRedraw(true);
322     state.setUpdateMoreResourcesPending(false);
323     state.setVisible(true);
324     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES, state.nextAction());
325
326     // Begin an update.
327     state.updateState(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES);
328
329     // Ensure we draw on the next vsync even though an update is in-progress.
330     state.didEnterVSync();
331     EXPECT_EQ(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
332     state.updateState(CCSchedulerStateMachine::ACTION_DRAW);
333
334     // Ensure that we once we have drawn, we dont do anything else.
335     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
336
337     // Leave the vsync before we finish the update.
338     state.didLeaveVSync();
339
340     // Finish update but leave more resources pending.
341     state.beginUpdateMoreResourcesComplete(true);
342
343     // Verify that regardless of vsync, we update some more.
344     state.didLeaveVSync();
345     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES, state.nextAction());
346     state.didEnterVSync();
347     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES, state.nextAction());
348     state.didEnterVSync();
349     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES, state.nextAction());
350
351     // Begin another update. Finish it immediately. Inside the vsync.
352     state.didEnterVSync();
353     state.updateState(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES);
354     state.didLeaveVSync();
355     state.beginUpdateMoreResourcesComplete(false);
356
357     // Verify we commit regardless of vsync state
358     state.didLeaveVSync();
359     EXPECT_EQ(CCSchedulerStateMachine::ACTION_COMMIT, state.nextAction());
360     state.didEnterVSync();
361     EXPECT_EQ(CCSchedulerStateMachine::ACTION_COMMIT, state.nextAction());
362 }
363
364 TEST(CCSchedulerStateMachineTest, TestSetNeedsCommitIsNotLost)
365 {
366     StateMachine state;
367     state.setNeedsCommit(true);
368     state.setVisible(true);
369
370     // Begin the frame.
371     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
372     state.updateState(state.nextAction());
373     EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState());
374
375     // Now, while the frame is in progress, set another commit.
376     state.setNeedsCommit(true);
377     EXPECT_TRUE(state.needsCommit());
378
379     // Let the frame finish.
380     state.beginFrameComplete();
381     EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_UPDATING_RESOURCES, state.commitState());
382     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES, state.nextAction());
383     state.updateState(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES);
384     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
385     state.beginUpdateMoreResourcesComplete(false);
386     EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, state.commitState());
387
388     // Expect to commit regardless of vsync state.
389     state.didLeaveVSync();
390     EXPECT_EQ(CCSchedulerStateMachine::ACTION_COMMIT, state.nextAction());
391     state.didEnterVSync();
392     EXPECT_EQ(CCSchedulerStateMachine::ACTION_COMMIT, state.nextAction());
393
394     // Commit and make sure we draw on next vsync
395     state.updateState(CCSchedulerStateMachine::ACTION_COMMIT);
396     EXPECT_EQ(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
397     EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, state.commitState());
398     state.updateState(CCSchedulerStateMachine::ACTION_DRAW);
399
400     // Verify that another commit will begin.
401     state.didLeaveVSync();
402     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
403 }
404
405 TEST(CCSchedulerStateMachineTest, TestFullCycle)
406 {
407     StateMachine state;
408     state.setVisible(true);
409
410     // Start clean and set commit.
411     state.setNeedsCommit(true);
412     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
413
414     // Begin the frame.
415     state.updateState(CCSchedulerStateMachine::ACTION_BEGIN_FRAME);
416     EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState());
417     EXPECT_FALSE(state.needsCommit());
418     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
419
420     // Tell the scheduler the frame finished.
421     state.beginFrameComplete();
422     EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_UPDATING_RESOURCES, state.commitState());
423     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES, state.nextAction());
424
425     // Tell the scheduler the update began and finished
426     state.updateState(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES);
427     state.beginUpdateMoreResourcesComplete(false);
428     EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, state.commitState());
429     EXPECT_EQ(CCSchedulerStateMachine::ACTION_COMMIT, state.nextAction());
430
431     // Commit.
432     state.updateState(CCSchedulerStateMachine::ACTION_COMMIT);
433     EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_IDLE, state.commitState());
434     EXPECT_TRUE(state.needsRedraw());
435
436     // Expect to do nothing until vsync.
437     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
438
439     // At vsync, draw.
440     state.didEnterVSync();
441     EXPECT_EQ(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
442     state.updateState(CCSchedulerStateMachine::ACTION_DRAW);
443     state.didLeaveVSync();
444
445     // Should be synchronized, no draw needed, no action needed.
446     EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_IDLE, state.commitState());
447     EXPECT_FALSE(state.needsRedraw());
448     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
449 }
450
451 TEST(CCSchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween)
452 {
453     StateMachine state;
454     state.setVisible(true);
455
456     // Start clean and set commit.
457     state.setNeedsCommit(true);
458     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
459
460     // Begin the frame.
461     state.updateState(CCSchedulerStateMachine::ACTION_BEGIN_FRAME);
462     EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState());
463     EXPECT_FALSE(state.needsCommit());
464     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
465
466     // Request another commit while the commit is in flight.
467     state.setNeedsCommit(true);
468     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
469
470     // Tell the scheduler the frame finished.
471     state.beginFrameComplete();
472     EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_UPDATING_RESOURCES, state.commitState());
473     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES, state.nextAction());
474
475     // Tell the scheduler the update began and finished
476     state.updateState(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES);
477     state.beginUpdateMoreResourcesComplete(false);
478     EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, state.commitState());
479     EXPECT_EQ(CCSchedulerStateMachine::ACTION_COMMIT, state.nextAction());
480
481     // Commit.
482     state.updateState(CCSchedulerStateMachine::ACTION_COMMIT);
483     EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, state.commitState());
484     EXPECT_TRUE(state.needsRedraw());
485
486     // Expect to do nothing until vsync.
487     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
488
489     // At vsync, draw.
490     state.didEnterVSync();
491     EXPECT_EQ(CCSchedulerStateMachine::ACTION_DRAW, state.nextAction());
492     state.updateState(CCSchedulerStateMachine::ACTION_DRAW);
493     state.didLeaveVSync();
494
495     // Should be synchronized, no draw needed, no action needed.
496     EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_IDLE, state.commitState());
497     EXPECT_FALSE(state.needsRedraw());
498     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
499 }
500
501 TEST(CCSchedulerStateMachineTest, TestRequestCommitInvisible)
502 {
503     StateMachine state;
504     state.setNeedsCommit(true);
505     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
506 }
507
508 TEST(CCSchedulerStateMachineTest, TestGoesInvisibleMidCommit)
509 {
510     StateMachine state;
511     state.setVisible(true);
512
513     // Start clean and set commit.
514     state.setNeedsCommit(true);
515     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_FRAME, state.nextAction());
516
517     // Begin the frame while visible.
518     state.updateState(CCSchedulerStateMachine::ACTION_BEGIN_FRAME);
519     EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_FRAME_IN_PROGRESS, state.commitState());
520     EXPECT_FALSE(state.needsCommit());
521     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
522
523     // Become invisible
524     state.setVisible(false);
525
526     // Tell the scheduler the frame finished
527     state.beginFrameComplete();
528     EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_UPDATING_RESOURCES, state.commitState());
529     EXPECT_EQ(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES, state.nextAction());
530
531     // Tell the scheduler the update began and finished
532     state.updateState(CCSchedulerStateMachine::ACTION_BEGIN_UPDATE_MORE_RESOURCES);
533     state.beginUpdateMoreResourcesComplete(false);
534     EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_READY_TO_COMMIT, state.commitState());
535     EXPECT_EQ(CCSchedulerStateMachine::ACTION_COMMIT, state.nextAction());
536
537     // Commit in invisible state should leave us:
538     // - COMMIT_STATE_WAITING_FOR_FIRST_DRAW
539     // - Waiting for redraw.
540     // - No commit needed
541     state.updateState(CCSchedulerStateMachine::ACTION_COMMIT);
542     EXPECT_EQ(CCSchedulerStateMachine::COMMIT_STATE_WAITING_FOR_FIRST_DRAW, state.commitState());
543     EXPECT_TRUE(state.needsRedraw());
544     EXPECT_FALSE(state.needsCommit());
545
546     // Expect to do nothing, both in and out of vsync.
547     state.didLeaveVSync();
548     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
549     state.didEnterVSync();
550     EXPECT_EQ(CCSchedulerStateMachine::ACTION_NONE, state.nextAction());
551 }
552
553 }