blob: 63142b276875fb638545df35f321deafc308a0b4 [file] [log] [blame]
[email protected]94f206c12012-08-25 00:09:141// 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.
4
[email protected]aa0a9d32012-10-24 01:58:105#include "cc/frame_rate_controller.h"
[email protected]94f206c12012-08-25 00:09:146
[email protected]101441ce2012-10-16 01:45:037#include "cc/test/scheduler_test_common.h"
[email protected]7f0c53db2012-10-02 00:23:188#include "testing/gtest/include/gtest/gtest.h"
[email protected]94f206c12012-08-25 00:09:149
[email protected]94f206c12012-08-25 00:09:1410using namespace WebKitTests;
11
[email protected]ba565742012-11-10 09:29:4812namespace cc {
[email protected]94f206c12012-08-25 00:09:1413namespace {
14
[email protected]96baf3e2012-10-22 23:09:5515class FakeFrameRateControllerClient : public cc::FrameRateControllerClient {
[email protected]94f206c12012-08-25 00:09:1416public:
[email protected]96baf3e2012-10-22 23:09:5517 FakeFrameRateControllerClient() { reset(); }
[email protected]94f206c12012-08-25 00:09:1418
19 void reset() { m_vsyncTicked = false; }
20 bool vsyncTicked() const { return m_vsyncTicked; }
21
[email protected]c1d368e2012-10-02 16:34:4522 virtual void vsyncTick(bool throttled) { m_vsyncTicked = !throttled; }
[email protected]94f206c12012-08-25 00:09:1423
24protected:
25 bool m_vsyncTicked;
26};
27
28
[email protected]96baf3e2012-10-22 23:09:5529TEST(FrameRateControllerTest, TestFrameThrottling_ImmediateAck)
[email protected]94f206c12012-08-25 00:09:1430{
[email protected]96baf3e2012-10-22 23:09:5531 FakeThread thread;
32 FakeFrameRateControllerClient client;
[email protected]4481ddb622012-09-20 16:33:4733 base::TimeDelta interval = base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond / 60);
[email protected]96baf3e2012-10-22 23:09:5534 scoped_refptr<FakeDelayBasedTimeSource> timeSource = FakeDelayBasedTimeSource::create(interval, &thread);
35 FrameRateController controller(timeSource);
[email protected]94f206c12012-08-25 00:09:1436
37 controller.setClient(&client);
38 controller.setActive(true);
39
[email protected]4481ddb622012-09-20 16:33:4740 base::TimeTicks elapsed; // Muck around with time a bit
[email protected]94f206c12012-08-25 00:09:1441
42 // Trigger one frame, make sure the vsync callback is called
[email protected]4481ddb622012-09-20 16:33:4743 elapsed += base::TimeDelta::FromMilliseconds(thread.pendingDelayMs());
44 timeSource->setNow(elapsed);
[email protected]94f206c12012-08-25 00:09:1445 thread.runPendingTask();
46 EXPECT_TRUE(client.vsyncTicked());
47 client.reset();
48
49 // Tell the controller we drew
50 controller.didBeginFrame();
51
52 // Tell the controller the frame ended 5ms later
[email protected]4481ddb622012-09-20 16:33:4753 timeSource->setNow(timeSource->now() + base::TimeDelta::FromMilliseconds(5));
[email protected]94f206c12012-08-25 00:09:1454 controller.didFinishFrame();
55
56 // Trigger another frame, make sure vsync runs again
[email protected]4481ddb622012-09-20 16:33:4757 elapsed += base::TimeDelta::FromMilliseconds(thread.pendingDelayMs());
58 EXPECT_TRUE(elapsed >= timeSource->now()); // Sanity check that previous code didn't move time backward.
59 timeSource->setNow(elapsed);
[email protected]94f206c12012-08-25 00:09:1460 thread.runPendingTask();
61 EXPECT_TRUE(client.vsyncTicked());
62}
63
[email protected]96baf3e2012-10-22 23:09:5564TEST(FrameRateControllerTest, TestFrameThrottling_TwoFramesInFlight)
[email protected]94f206c12012-08-25 00:09:1465{
[email protected]96baf3e2012-10-22 23:09:5566 FakeThread thread;
67 FakeFrameRateControllerClient client;
[email protected]4481ddb622012-09-20 16:33:4768 base::TimeDelta interval = base::TimeDelta::FromMicroseconds(base::Time::kMicrosecondsPerSecond / 60);
[email protected]96baf3e2012-10-22 23:09:5569 scoped_refptr<FakeDelayBasedTimeSource> timeSource = FakeDelayBasedTimeSource::create(interval, &thread);
70 FrameRateController controller(timeSource);
[email protected]94f206c12012-08-25 00:09:1471
72 controller.setClient(&client);
73 controller.setActive(true);
74 controller.setMaxFramesPending(2);
75
[email protected]4481ddb622012-09-20 16:33:4776 base::TimeTicks elapsed; // Muck around with time a bit
[email protected]94f206c12012-08-25 00:09:1477
78 // Trigger one frame, make sure the vsync callback is called
[email protected]4481ddb622012-09-20 16:33:4779 elapsed += base::TimeDelta::FromMilliseconds(thread.pendingDelayMs());
80 timeSource->setNow(elapsed);
[email protected]94f206c12012-08-25 00:09:1481 thread.runPendingTask();
82 EXPECT_TRUE(client.vsyncTicked());
83 client.reset();
84
85 // Tell the controller we drew
86 controller.didBeginFrame();
87
88 // Trigger another frame, make sure vsync callback runs again
[email protected]4481ddb622012-09-20 16:33:4789 elapsed += base::TimeDelta::FromMilliseconds(thread.pendingDelayMs());
90 EXPECT_TRUE(elapsed >= timeSource->now()); // Sanity check that previous code didn't move time backward.
91 timeSource->setNow(elapsed);
[email protected]94f206c12012-08-25 00:09:1492 thread.runPendingTask();
93 EXPECT_TRUE(client.vsyncTicked());
94 client.reset();
95
96 // Tell the controller we drew, again.
97 controller.didBeginFrame();
98
99 // Trigger another frame. Since two frames are pending, we should not draw.
[email protected]4481ddb622012-09-20 16:33:47100 elapsed += base::TimeDelta::FromMilliseconds(thread.pendingDelayMs());
101 EXPECT_TRUE(elapsed >= timeSource->now()); // Sanity check that previous code didn't move time backward.
102 timeSource->setNow(elapsed);
[email protected]94f206c12012-08-25 00:09:14103 thread.runPendingTask();
104 EXPECT_FALSE(client.vsyncTicked());
105
106 // Tell the controller the first frame ended 5ms later
[email protected]4481ddb622012-09-20 16:33:47107 timeSource->setNow(timeSource->now() + base::TimeDelta::FromMilliseconds(5));
[email protected]94f206c12012-08-25 00:09:14108 controller.didFinishFrame();
109
110 // Tick should not have been called
111 EXPECT_FALSE(client.vsyncTicked());
112
113 // Trigger yet another frame. Since one frames is pending, another vsync callback should run.
[email protected]4481ddb622012-09-20 16:33:47114 elapsed += base::TimeDelta::FromMilliseconds(thread.pendingDelayMs());
115 EXPECT_TRUE(elapsed >= timeSource->now()); // Sanity check that previous code didn't move time backward.
116 timeSource->setNow(elapsed);
[email protected]94f206c12012-08-25 00:09:14117 thread.runPendingTask();
118 EXPECT_TRUE(client.vsyncTicked());
119}
120
[email protected]96baf3e2012-10-22 23:09:55121TEST(FrameRateControllerTest, TestFrameThrottling_Unthrottled)
[email protected]94f206c12012-08-25 00:09:14122{
[email protected]96baf3e2012-10-22 23:09:55123 FakeThread thread;
124 FakeFrameRateControllerClient client;
125 FrameRateController controller(&thread);
[email protected]94f206c12012-08-25 00:09:14126
127 controller.setClient(&client);
128 controller.setMaxFramesPending(2);
129
130 // setActive triggers 1st frame, make sure the vsync callback is called
131 controller.setActive(true);
132 thread.runPendingTask();
133 EXPECT_TRUE(client.vsyncTicked());
134 client.reset();
135
[email protected]96baf3e2012-10-22 23:09:55136 // Even if we don't call didBeginFrame, FrameRateController should
[email protected]94f206c12012-08-25 00:09:14137 // still attempt to vsync tick multiple times until it does result in
138 // a didBeginFrame.
139 thread.runPendingTask();
140 EXPECT_TRUE(client.vsyncTicked());
141 client.reset();
142
143 thread.runPendingTask();
144 EXPECT_TRUE(client.vsyncTicked());
145 client.reset();
146
147 // didBeginFrame triggers 2nd frame, make sure the vsync callback is called
148 controller.didBeginFrame();
149 thread.runPendingTask();
150 EXPECT_TRUE(client.vsyncTicked());
151 client.reset();
152
153 // didBeginFrame triggers 3rd frame (> maxFramesPending), make sure the vsync callback is NOT called
154 controller.didBeginFrame();
155 thread.runPendingTask();
156 EXPECT_FALSE(client.vsyncTicked());
157 client.reset();
158
159 // Make sure there is no pending task since we can't do anything until we receive a didFinishFrame anyway.
160 EXPECT_FALSE(thread.hasPendingTask());
161
162 // didFinishFrame triggers a frame, make sure the vsync callback is called
163 controller.didFinishFrame();
164 thread.runPendingTask();
165 EXPECT_TRUE(client.vsyncTicked());
166}
167
[email protected]ba565742012-11-10 09:29:48168} // namespace
169} // namespace cc