OLD | NEW |
---|---|
1 // Copyright 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "cc/scheduler/frame_rate_controller.h" | 5 #include "cc/scheduler/frame_rate_controller.h" |
6 | 6 |
7 #include "base/test/test_simple_task_runner.h" | 7 #include "base/test/test_simple_task_runner.h" |
8 #include "cc/test/scheduler_test_common.h" | 8 #include "cc/test/scheduler_test_common.h" |
9 #include "testing/gtest/include/gtest/gtest.h" | 9 #include "testing/gtest/include/gtest/gtest.h" |
10 | 10 |
11 namespace cc { | 11 namespace cc { |
12 namespace { | 12 namespace { |
13 | 13 |
14 class FakeFrameRateControllerClient : public FrameRateControllerClient { | 14 class FakeFrameRateControllerClient : public FrameRateControllerClient { |
15 public: | 15 public: |
16 FakeFrameRateControllerClient() { Reset(); } | 16 FakeFrameRateControllerClient() { Reset(); } |
17 | 17 |
18 void Reset() { frame_count_ = 0; } | 18 void Reset() { frame_count_ = 0; } |
19 bool BeganFrame() const { return frame_count_ > 0; } | 19 bool BeganFrame() const { return frame_count_ > 0; } |
20 int frame_count() const { return frame_count_; } | 20 int frame_count() const { return frame_count_; } |
21 | 21 |
22 virtual void FrameRateControllerTick( | 22 virtual void FrameRateControllerTick(const BeginFrameArgs& args) OVERRIDE { |
23 bool throttled, const BeginFrameArgs& args) OVERRIDE { | 23 frame_count_ += 1; |
24 frame_count_ += throttled ? 0 : 1; | |
25 } | 24 } |
26 | 25 |
27 protected: | 26 protected: |
28 int frame_count_; | 27 int frame_count_; |
29 }; | 28 }; |
30 | 29 |
31 TEST(FrameRateControllerTest, TestFrameThrottling_ImmediateAck) { | 30 TEST(FrameRateControllerTest, TestFrameThrottling_ImmediateAck) { |
32 scoped_refptr<base::TestSimpleTaskRunner> task_runner = | 31 scoped_refptr<base::TestSimpleTaskRunner> task_runner = |
33 new base::TestSimpleTaskRunner; | 32 new base::TestSimpleTaskRunner; |
34 FakeFrameRateControllerClient client; | 33 FakeFrameRateControllerClient client; |
35 base::TimeDelta interval = base::TimeDelta::FromMicroseconds( | 34 base::TimeDelta interval = base::TimeDelta::FromMicroseconds( |
36 base::Time::kMicrosecondsPerSecond / 60); | 35 base::Time::kMicrosecondsPerSecond / 60); |
37 scoped_refptr<FakeDelayBasedTimeSource> time_source = | 36 scoped_refptr<FakeDelayBasedTimeSource> time_source = |
38 FakeDelayBasedTimeSource::Create(interval, task_runner.get()); | 37 FakeDelayBasedTimeSource::Create(interval, task_runner.get()); |
39 FrameRateController controller(time_source); | 38 FrameRateController controller(time_source); |
40 | 39 |
41 controller.SetClient(&client); | 40 controller.SetClient(&client); |
42 controller.SetActive(true); | 41 controller.SetActive(true); |
43 | 42 |
44 base::TimeTicks elapsed; // Muck around with time a bit | 43 base::TimeTicks elapsed; // Muck around with time a bit |
45 | 44 |
46 // Trigger one frame, make sure the BeginFrame callback is called | 45 // Trigger one frame, make sure the BeginFrame callback is called |
47 elapsed += task_runner->NextPendingTaskDelay(); | 46 elapsed += task_runner->NextPendingTaskDelay(); |
48 time_source->SetNow(elapsed); | 47 time_source->SetNow(elapsed); |
49 task_runner->RunPendingTasks(); | 48 task_runner->RunPendingTasks(); |
50 EXPECT_TRUE(client.BeganFrame()); | 49 EXPECT_TRUE(client.BeganFrame()); |
51 client.Reset(); | 50 client.Reset(); |
52 | 51 |
53 // Tell the controller we drew | |
54 controller.DidSwapBuffers(); | |
55 | |
56 // Tell the controller the frame ended 5ms later | |
57 time_source->SetNow(time_source->Now() + | |
58 base::TimeDelta::FromMilliseconds(5)); | |
59 controller.DidSwapBuffersComplete(); | |
60 | |
61 // Trigger another frame, make sure BeginFrame runs again | 52 // Trigger another frame, make sure BeginFrame runs again |
62 elapsed += task_runner->NextPendingTaskDelay(); | 53 elapsed += task_runner->NextPendingTaskDelay(); |
63 // Sanity check that previous code didn't move time backward. | 54 // Sanity check that previous code didn't move time backward. |
64 EXPECT_GE(elapsed, time_source->Now()); | 55 EXPECT_GE(elapsed, time_source->Now()); |
65 time_source->SetNow(elapsed); | 56 time_source->SetNow(elapsed); |
66 task_runner->RunPendingTasks(); | 57 task_runner->RunPendingTasks(); |
67 EXPECT_TRUE(client.BeganFrame()); | 58 EXPECT_TRUE(client.BeganFrame()); |
68 } | 59 } |
69 | 60 |
70 TEST(FrameRateControllerTest, TestFrameThrottling_TwoFramesInFlight) { | |
brianderson
2014/03/13 21:11:52
I need to port these tests over to the scheduler.
| |
71 scoped_refptr<base::TestSimpleTaskRunner> task_runner = | |
72 new base::TestSimpleTaskRunner; | |
73 FakeFrameRateControllerClient client; | |
74 base::TimeDelta interval = base::TimeDelta::FromMicroseconds( | |
75 base::Time::kMicrosecondsPerSecond / 60); | |
76 scoped_refptr<FakeDelayBasedTimeSource> time_source = | |
77 FakeDelayBasedTimeSource::Create(interval, task_runner.get()); | |
78 FrameRateController controller(time_source); | |
79 | |
80 controller.SetClient(&client); | |
81 controller.SetActive(true); | |
82 controller.SetMaxSwapsPending(2); | |
83 | |
84 base::TimeTicks elapsed; // Muck around with time a bit | |
85 | |
86 // Trigger one frame, make sure the BeginFrame callback is called | |
87 elapsed += task_runner->NextPendingTaskDelay(); | |
88 time_source->SetNow(elapsed); | |
89 task_runner->RunPendingTasks(); | |
90 EXPECT_TRUE(client.BeganFrame()); | |
91 client.Reset(); | |
92 | |
93 // Tell the controller we drew | |
94 controller.DidSwapBuffers(); | |
95 | |
96 // Trigger another frame, make sure BeginFrame callback runs again | |
97 elapsed += task_runner->NextPendingTaskDelay(); | |
98 // Sanity check that previous code didn't move time backward. | |
99 EXPECT_GE(elapsed, time_source->Now()); | |
100 time_source->SetNow(elapsed); | |
101 task_runner->RunPendingTasks(); | |
102 EXPECT_TRUE(client.BeganFrame()); | |
103 client.Reset(); | |
104 | |
105 // Tell the controller we drew, again. | |
106 controller.DidSwapBuffers(); | |
107 | |
108 // Trigger another frame. Since two frames are pending, we should not draw. | |
109 elapsed += task_runner->NextPendingTaskDelay(); | |
110 // Sanity check that previous code didn't move time backward. | |
111 EXPECT_GE(elapsed, time_source->Now()); | |
112 time_source->SetNow(elapsed); | |
113 task_runner->RunPendingTasks(); | |
114 EXPECT_FALSE(client.BeganFrame()); | |
115 | |
116 // Tell the controller the first frame ended 5ms later | |
117 time_source->SetNow(time_source->Now() + | |
118 base::TimeDelta::FromMilliseconds(5)); | |
119 controller.DidSwapBuffersComplete(); | |
120 | |
121 // Tick should not have been called | |
122 EXPECT_FALSE(client.BeganFrame()); | |
123 | |
124 // Trigger yet another frame. Since one frames is pending, another | |
125 // BeginFrame callback should run. | |
126 elapsed += task_runner->NextPendingTaskDelay(); | |
127 // Sanity check that previous code didn't move time backward. | |
128 EXPECT_GE(elapsed, time_source->Now()); | |
129 time_source->SetNow(elapsed); | |
130 task_runner->RunPendingTasks(); | |
131 EXPECT_TRUE(client.BeganFrame()); | |
132 } | |
133 | |
134 TEST(FrameRateControllerTest, TestFrameThrottling_Unthrottled) { | |
135 scoped_refptr<base::TestSimpleTaskRunner> task_runner = | |
136 new base::TestSimpleTaskRunner; | |
137 FakeFrameRateControllerClient client; | |
138 FrameRateController controller(task_runner.get()); | |
139 | |
140 controller.SetClient(&client); | |
141 controller.SetMaxSwapsPending(2); | |
142 | |
143 // SetActive triggers 1st frame, make sure the BeginFrame callback | |
144 // is called | |
145 controller.SetActive(true); | |
146 task_runner->RunPendingTasks(); | |
147 EXPECT_TRUE(client.BeganFrame()); | |
148 client.Reset(); | |
149 | |
150 // Even if we don't call DidSwapBuffers, FrameRateController should | |
151 // still attempt to tick multiple times until it does result in | |
152 // a DidSwapBuffers. | |
153 task_runner->RunPendingTasks(); | |
154 EXPECT_TRUE(client.BeganFrame()); | |
155 client.Reset(); | |
156 | |
157 task_runner->RunPendingTasks(); | |
158 EXPECT_TRUE(client.BeganFrame()); | |
159 client.Reset(); | |
160 | |
161 // DidSwapBuffers triggers 2nd frame, make sure the BeginFrame callback is | |
162 // called | |
163 controller.DidSwapBuffers(); | |
164 task_runner->RunPendingTasks(); | |
165 EXPECT_TRUE(client.BeganFrame()); | |
166 client.Reset(); | |
167 | |
168 // DidSwapBuffers triggers 3rd frame (> max_frames_pending), | |
169 // make sure the BeginFrame callback is NOT called | |
170 controller.DidSwapBuffers(); | |
171 task_runner->RunPendingTasks(); | |
172 EXPECT_FALSE(client.BeganFrame()); | |
173 client.Reset(); | |
174 | |
175 // Make sure there is no pending task since we can't do anything until we | |
176 // receive a DidSwapBuffersComplete anyway. | |
177 EXPECT_FALSE(task_runner->HasPendingTask()); | |
178 | |
179 // DidSwapBuffersComplete triggers a frame, make sure the BeginFrame | |
180 // callback is called | |
181 controller.DidSwapBuffersComplete(); | |
182 task_runner->RunPendingTasks(); | |
183 EXPECT_TRUE(client.BeganFrame()); | |
184 } | |
185 | |
186 TEST(FrameRateControllerTest, TestFrameThrottling_NoDoubleTicking) { | |
187 scoped_refptr<base::TestSimpleTaskRunner> task_runner = | |
188 new base::TestSimpleTaskRunner; | |
189 FakeFrameRateControllerClient client; | |
190 FrameRateController controller(task_runner.get()); | |
191 controller.SetClient(&client); | |
192 | |
193 // SetActive triggers 1st frame and queues another tick task since the time | |
194 // source isn't throttling. | |
195 controller.SetActive(true); | |
196 task_runner->RunPendingTasks(); | |
197 EXPECT_TRUE(client.BeganFrame()); | |
198 client.Reset(); | |
199 EXPECT_TRUE(task_runner->HasPendingTask()); | |
200 | |
201 // Simulate a frame swap. This shouldn't queue a second tick task. | |
202 controller.DidSwapBuffers(); | |
203 controller.DidSwapBuffersComplete(); | |
204 | |
205 // The client should only be ticked once. | |
206 task_runner->RunPendingTasks(); | |
207 EXPECT_EQ(1, client.frame_count()); | |
208 } | |
209 | |
210 } // namespace | 61 } // namespace |
211 } // namespace cc | 62 } // namespace cc |
OLD | NEW |