f315903901abe862b84c1093ead1dfa6e142f837
[WebKit-https.git] / Source / WebKit / chromium / tests / CCFrameRateControllerTest.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/CCFrameRateController.h"
28
29 #include "CCSchedulerTestCommon.h"
30 #include <gtest/gtest.h>
31
32 using namespace WTF;
33 using namespace WebCore;
34 using namespace WebKitTests;
35
36 namespace {
37
38 class FakeCCFrameRateControllerClient : public WebCore::CCFrameRateControllerClient {
39 public:
40     FakeCCFrameRateControllerClient() { reset(); }
41
42     void reset() { m_vsyncTicked = false; }
43     bool vsyncTicked() const { return m_vsyncTicked; }
44
45     virtual void vsyncTick() { m_vsyncTicked = true; }
46
47 protected:
48     bool m_vsyncTicked;
49 };
50
51
52 TEST(CCFrameRateControllerTest, TestFrameThrottling_ImmediateAck)
53 {
54     FakeCCThread thread;
55     FakeCCFrameRateControllerClient client;
56     RefPtr<FakeCCDelayBasedTimeSource> timeSource = FakeCCDelayBasedTimeSource::create(1000.0 / 60.0, &thread);
57     CCFrameRateController controller(timeSource);
58
59     controller.setClient(&client);
60     controller.setActive(true);
61
62     double elapsed = 0; // Muck around with time a bit
63
64     // Trigger one frame, make sure the vsync callback is called
65     elapsed += thread.pendingDelay();
66     timeSource->setMonotonicallyIncreasingTimeMs(elapsed);
67     thread.runPendingTask();
68     EXPECT_TRUE(client.vsyncTicked());
69     client.reset();
70
71     // Tell the controller we drew
72     controller.didBeginFrame();
73
74     // Tell the controller the frame ended 5ms later
75     timeSource->setMonotonicallyIncreasingTimeMs(timeSource->monotonicallyIncreasingTimeMs() + 5);
76     controller.didFinishFrame();
77
78     // Trigger another frame, make sure vsync runs again
79     elapsed += thread.pendingDelay();
80     EXPECT_TRUE(elapsed >= timeSource->monotonicallyIncreasingTimeMs()); // Sanity check that previous code didn't move time backward.
81     timeSource->setMonotonicallyIncreasingTimeMs(elapsed);
82     thread.runPendingTask();
83     EXPECT_TRUE(client.vsyncTicked());
84 }
85
86 TEST(CCFrameRateControllerTest, TestFrameThrottling_TwoFramesInFlight)
87 {
88     FakeCCThread thread;
89     FakeCCFrameRateControllerClient client;
90     RefPtr<FakeCCDelayBasedTimeSource> timeSource = FakeCCDelayBasedTimeSource::create(1000.0 / 60.0, &thread);
91     CCFrameRateController controller(timeSource);
92
93     controller.setClient(&client);
94     controller.setActive(true);
95     controller.setMaxFramesPending(2);
96
97     double elapsed = 0; // Muck around with time a bit
98
99     // Trigger one frame, make sure the vsync callback is called
100     elapsed += thread.pendingDelay();
101     timeSource->setMonotonicallyIncreasingTimeMs(elapsed);
102     thread.runPendingTask();
103     EXPECT_TRUE(client.vsyncTicked());
104     client.reset();
105
106     // Tell the controller we drew
107     controller.didBeginFrame();
108
109     // Trigger another frame, make sure vsync callback runs again
110     elapsed += thread.pendingDelay();
111     EXPECT_TRUE(elapsed >= timeSource->monotonicallyIncreasingTimeMs()); // Sanity check that previous code didn't move time backward.
112     timeSource->setMonotonicallyIncreasingTimeMs(elapsed);
113     thread.runPendingTask();
114     EXPECT_TRUE(client.vsyncTicked());
115     client.reset();
116
117     // Tell the controller we drew, again.
118     controller.didBeginFrame();
119
120     // Trigger another frame. Since two frames are pending, we should not draw.
121     elapsed += thread.pendingDelay();
122     EXPECT_TRUE(elapsed >= timeSource->monotonicallyIncreasingTimeMs()); // Sanity check that previous code didn't move time backward.
123     timeSource->setMonotonicallyIncreasingTimeMs(elapsed);
124     thread.runPendingTask();
125     EXPECT_FALSE(client.vsyncTicked());
126
127     // Tell the controller the first frame ended 5ms later
128     timeSource->setMonotonicallyIncreasingTimeMs(timeSource->monotonicallyIncreasingTimeMs() + 5);
129     controller.didFinishFrame();
130
131     // Tick should not have been called
132     EXPECT_FALSE(client.vsyncTicked());
133
134     // Trigger yet another frame. Since one frames is pending, another vsync callback should run.
135     elapsed += thread.pendingDelay();
136     EXPECT_TRUE(elapsed >= timeSource->monotonicallyIncreasingTimeMs()); // Sanity check that previous code didn't move time backward.
137     timeSource->setMonotonicallyIncreasingTimeMs(elapsed);
138     thread.runPendingTask();
139     EXPECT_TRUE(client.vsyncTicked());
140 }
141
142 }