OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 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 | |
5 #include "content/renderer/scheduler/renderer_scheduler_impl.h" | |
6 | |
7 #include "base/callback.h" | |
8 #include "cc/output/begin_frame_args.h" | |
9 #include "cc/test/ordered_simple_task_runner.h" | |
10 #include "testing/gmock/include/gmock/gmock.h" | |
11 #include "testing/gtest/include/gtest/gtest.h" | |
12 | |
13 namespace content { | |
14 | |
15 class RendererSchedulerImplForTest : public RendererSchedulerImpl { | |
16 public: | |
17 RendererSchedulerImplForTest( | |
18 scoped_refptr<cc::OrderedSimpleTaskRunner> task_runner, | |
19 scoped_refptr<cc::TestNowSource> clock) | |
20 : RendererSchedulerImpl(task_runner), clock_(clock) {} | |
21 ~RendererSchedulerImplForTest() override {} | |
22 | |
23 protected: | |
24 base::TimeTicks Now() const override { return clock_->Now(); } | |
25 | |
26 private: | |
27 scoped_refptr<cc::TestNowSource> clock_; | |
28 }; | |
29 | |
30 class RendererSchedulerImplTest : public testing::Test { | |
31 public: | |
32 RendererSchedulerImplTest() | |
33 : clock_(cc::TestNowSource::Create(5000)), | |
34 mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_, false)), | |
35 scheduler_(new RendererSchedulerImplForTest(mock_task_runner_, clock_)), | |
36 default_task_runner_(scheduler_->DefaultTaskRunner()), | |
37 compositor_task_runner_(scheduler_->CompositorTaskRunner()), | |
38 idle_task_runner_(scheduler_->IdleTaskRunner()) {} | |
39 ~RendererSchedulerImplTest() override {} | |
40 | |
41 void RunUntilIdle() { mock_task_runner_->RunUntilIdle(); } | |
42 | |
43 void EnableIdleTasks() { | |
44 scheduler_->WillBeginFrame( | |
45 cc::BeginFrameArgs::Create(clock_->Now(), | |
46 base::TimeTicks(), | |
47 base::TimeDelta::FromMilliseconds(1000))); | |
48 scheduler_->DidCommitFrameToCompositor(); | |
49 } | |
50 | |
51 protected: | |
52 scoped_refptr<cc::TestNowSource> clock_; | |
53 scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; | |
54 | |
55 scoped_ptr<RendererSchedulerImpl> scheduler_; | |
56 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; | |
57 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; | |
58 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; | |
59 | |
60 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImplTest); | |
61 }; | |
62 | |
63 void NullTask() { | |
64 } | |
65 | |
66 void OrderedTestTask(int value, int* result) { | |
67 *result = (*result << 4) | value; | |
68 } | |
69 | |
70 void UnorderedTestTask(int value, int* result) { | |
71 *result += value; | |
72 } | |
73 | |
74 void AppendToVectorTestTask(std::vector<std::string>* vector, | |
75 std::string value) { | |
76 vector->push_back(value); | |
77 } | |
78 | |
79 void AppendToVectorIdleTestTask(std::vector<std::string>* vector, | |
80 std::string value, | |
81 base::TimeTicks deadline) { | |
82 AppendToVectorTestTask(vector, value); | |
83 } | |
84 | |
85 void AppendToVectorReentrantTask( | |
86 scoped_refptr<base::SingleThreadTaskRunner> task_runner, | |
87 std::vector<int>* vector, | |
88 int* reentrant_count, | |
89 int max_reentrant_count) { | |
90 vector->push_back((*reentrant_count)++); | |
91 if (*reentrant_count < max_reentrant_count) { | |
92 task_runner->PostTask(FROM_HERE, | |
93 base::Bind(AppendToVectorReentrantTask, | |
94 task_runner, | |
95 vector, | |
96 reentrant_count, | |
97 max_reentrant_count)); | |
98 } | |
99 } | |
100 | |
101 void IdleTestTask(bool* task_run, | |
102 base::TimeTicks* deadline_out, | |
103 base::TimeTicks deadline) { | |
104 EXPECT_FALSE(*task_run); | |
105 *deadline_out = deadline; | |
106 *task_run = true; | |
107 } | |
108 | |
109 void RepostingIdleTestTask( | |
110 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner, | |
111 int* run_count, | |
112 base::TimeTicks deadline) { | |
113 if (*run_count == 0) | |
no sievers
2014/10/30 23:40:51
nit: braces
rmcilroy
2014/11/03 19:02:52
Done.
| |
114 idle_task_runner->PostIdleTask( | |
115 FROM_HERE, | |
116 base::Bind(&RepostingIdleTestTask, idle_task_runner, run_count)); | |
117 (*run_count)++; | |
118 } | |
119 | |
120 TEST_F(RendererSchedulerImplTest, TestPostDefaultTask) { | |
121 int result = 0; | |
122 default_task_runner_->PostTask(FROM_HERE, | |
123 base::Bind(OrderedTestTask, 1, &result)); | |
124 default_task_runner_->PostTask(FROM_HERE, | |
125 base::Bind(OrderedTestTask, 2, &result)); | |
126 default_task_runner_->PostTask(FROM_HERE, | |
127 base::Bind(OrderedTestTask, 3, &result)); | |
128 default_task_runner_->PostTask(FROM_HERE, | |
129 base::Bind(OrderedTestTask, 4, &result)); | |
130 RunUntilIdle(); | |
131 EXPECT_EQ(0x1234, result); | |
132 } | |
133 | |
134 TEST_F(RendererSchedulerImplTest, TestPostDefaultAndCompositor) { | |
135 int result = 0; | |
136 default_task_runner_->PostTask(FROM_HERE, | |
137 base::Bind(&UnorderedTestTask, 1, &result)); | |
138 compositor_task_runner_->PostTask(FROM_HERE, | |
139 base::Bind(&UnorderedTestTask, 2, &result)); | |
140 RunUntilIdle(); | |
141 EXPECT_EQ(3, result); | |
142 } | |
143 | |
144 TEST_F(RendererSchedulerImplTest, TestRentrantTask) { | |
145 int count = 0; | |
146 std::vector<int> order; | |
147 default_task_runner_->PostTask(FROM_HERE, | |
148 base::Bind(AppendToVectorReentrantTask, | |
149 default_task_runner_, | |
150 &order, | |
151 &count, | |
152 5)); | |
153 RunUntilIdle(); | |
154 | |
155 EXPECT_THAT(order, testing::ElementsAre(0, 1, 2, 3, 4)); | |
156 } | |
157 | |
158 TEST_F(RendererSchedulerImplTest, TestPostIdleTask) { | |
159 bool task_run = false; | |
160 base::TimeTicks expected_deadline = | |
161 clock_->Now() + base::TimeDelta::FromMilliseconds(2300); | |
162 base::TimeTicks deadline_in_task; | |
163 | |
164 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(100)); | |
165 idle_task_runner_->PostIdleTask( | |
166 FROM_HERE, base::Bind(&IdleTestTask, &task_run, &deadline_in_task)); | |
167 | |
168 RunUntilIdle(); | |
169 EXPECT_FALSE(task_run); // Shouldn't run yet as no WillBeginFrame. | |
170 | |
171 scheduler_->WillBeginFrame( | |
172 cc::BeginFrameArgs::Create(clock_->Now(), | |
173 base::TimeTicks(), | |
174 base::TimeDelta::FromMilliseconds(1000))); | |
175 RunUntilIdle(); | |
176 EXPECT_FALSE(task_run); // Shouldn't run as no DidCommitFrameToCompositor. | |
177 | |
178 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(1200)); | |
179 scheduler_->DidCommitFrameToCompositor(); | |
180 RunUntilIdle(); | |
181 EXPECT_FALSE(task_run); // We missed the deadline. | |
182 | |
183 scheduler_->WillBeginFrame( | |
184 cc::BeginFrameArgs::Create(clock_->Now(), | |
185 base::TimeTicks(), | |
186 base::TimeDelta::FromMilliseconds(1000))); | |
187 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(800)); | |
188 scheduler_->DidCommitFrameToCompositor(); | |
189 RunUntilIdle(); | |
190 EXPECT_TRUE(task_run); | |
191 EXPECT_EQ(expected_deadline, deadline_in_task); | |
192 } | |
193 | |
194 TEST_F(RendererSchedulerImplTest, TestRepostingIdleTask) { | |
195 int run_count = 0; | |
196 | |
197 idle_task_runner_->PostIdleTask( | |
198 FROM_HERE, | |
199 base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count)); | |
200 EnableIdleTasks(); | |
201 RunUntilIdle(); | |
202 EXPECT_EQ(1, run_count); | |
no sievers
2014/10/30 23:40:51
How many idle tasks is it expected to run? So it d
rmcilroy
2014/11/03 19:02:52
If we posted two tasks then we would expect both t
| |
203 | |
204 // Reposted tasks shouldn't run until next idle period. | |
205 RunUntilIdle(); | |
206 EXPECT_EQ(1, run_count); | |
207 | |
208 EnableIdleTasks(); | |
209 RunUntilIdle(); | |
210 EXPECT_EQ(2, run_count); | |
211 } | |
212 | |
213 TEST_F(RendererSchedulerImplTest, TestDefaultPolicy) { | |
214 std::vector<std::string> order; | |
215 | |
216 idle_task_runner_->PostIdleTask( | |
217 FROM_HERE, | |
218 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("I1"))); | |
219 default_task_runner_->PostTask( | |
220 FROM_HERE, | |
221 base::Bind(&AppendToVectorTestTask, &order, std::string("D1"))); | |
222 compositor_task_runner_->PostTask( | |
223 FROM_HERE, | |
224 base::Bind(&AppendToVectorTestTask, &order, std::string("C1"))); | |
225 default_task_runner_->PostTask( | |
226 FROM_HERE, | |
227 base::Bind(&AppendToVectorTestTask, &order, std::string("D2"))); | |
228 compositor_task_runner_->PostTask( | |
229 FROM_HERE, | |
230 base::Bind(&AppendToVectorTestTask, &order, std::string("C2"))); | |
231 | |
232 EnableIdleTasks(); | |
233 RunUntilIdle(); | |
234 EXPECT_THAT(order, | |
235 testing::ElementsAre(std::string("D1"), | |
236 std::string("C1"), | |
237 std::string("D2"), | |
238 std::string("C2"), | |
239 std::string("I1"))); | |
240 } | |
241 | |
242 TEST_F(RendererSchedulerImplTest, TestCompositorPolicy) { | |
243 std::vector<std::string> order; | |
244 | |
245 idle_task_runner_->PostIdleTask( | |
246 FROM_HERE, | |
247 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("I1"))); | |
248 default_task_runner_->PostTask( | |
249 FROM_HERE, | |
250 base::Bind(&AppendToVectorTestTask, &order, std::string("D1"))); | |
251 compositor_task_runner_->PostTask( | |
252 FROM_HERE, | |
253 base::Bind(&AppendToVectorTestTask, &order, std::string("C1"))); | |
254 default_task_runner_->PostTask( | |
255 FROM_HERE, | |
256 base::Bind(&AppendToVectorTestTask, &order, std::string("D2"))); | |
257 compositor_task_runner_->PostTask( | |
258 FROM_HERE, | |
259 base::Bind(&AppendToVectorTestTask, &order, std::string("C2"))); | |
260 | |
261 scheduler_->DidReceiveInputEvent(); | |
262 EnableIdleTasks(); | |
263 RunUntilIdle(); | |
264 EXPECT_THAT(order, | |
265 testing::ElementsAre(std::string("C1"), | |
266 std::string("C2"), | |
267 std::string("D1"), | |
268 std::string("D2"), | |
269 std::string("I1"))); | |
270 } | |
271 | |
272 TEST_F(RendererSchedulerImplTest, | |
273 TestCompositorPolicyDoesNotStarveDefaultTasks) { | |
274 std::vector<std::string> order; | |
275 | |
276 default_task_runner_->PostTask( | |
277 FROM_HERE, | |
278 base::Bind(&AppendToVectorTestTask, &order, std::string("D1"))); | |
279 compositor_task_runner_->PostTask( | |
280 FROM_HERE, | |
281 base::Bind(&AppendToVectorTestTask, &order, std::string("C1"))); | |
282 for (int i = 0; i < 20; i++) { | |
283 compositor_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask)); | |
284 } | |
285 compositor_task_runner_->PostTask( | |
286 FROM_HERE, | |
287 base::Bind(&AppendToVectorTestTask, &order, std::string("C2"))); | |
288 | |
289 scheduler_->DidReceiveInputEvent(); | |
290 RunUntilIdle(); | |
291 // Ensure that the default D1 task gets to run at some point before the final | |
292 // C2 compositor task. | |
293 EXPECT_THAT(order, | |
294 testing::ElementsAre( | |
295 std::string("C1"), std::string("D1"), std::string("C2"))); | |
296 } | |
297 | |
298 TEST_F(RendererSchedulerImplTest, TestCompositorPolicyEnds) { | |
299 std::vector<std::string> order; | |
300 | |
301 default_task_runner_->PostTask( | |
302 FROM_HERE, | |
303 base::Bind(&AppendToVectorTestTask, &order, std::string("D1"))); | |
304 compositor_task_runner_->PostTask( | |
305 FROM_HERE, | |
306 base::Bind(&AppendToVectorTestTask, &order, std::string("C1"))); | |
307 default_task_runner_->PostTask( | |
308 FROM_HERE, | |
309 base::Bind(&AppendToVectorTestTask, &order, std::string("D2"))); | |
310 compositor_task_runner_->PostTask( | |
311 FROM_HERE, | |
312 base::Bind(&AppendToVectorTestTask, &order, std::string("C2"))); | |
313 | |
314 scheduler_->DidReceiveInputEvent(); | |
315 RunUntilIdle(); | |
316 EXPECT_THAT(order, | |
317 testing::ElementsAre(std::string("C1"), | |
318 std::string("C2"), | |
319 std::string("D1"), | |
320 std::string("D2"))); | |
321 | |
322 order.clear(); | |
323 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(1000)); | |
324 | |
325 default_task_runner_->PostTask( | |
326 FROM_HERE, | |
327 base::Bind(&AppendToVectorTestTask, &order, std::string("D1"))); | |
328 compositor_task_runner_->PostTask( | |
329 FROM_HERE, | |
330 base::Bind(&AppendToVectorTestTask, &order, std::string("C1"))); | |
331 default_task_runner_->PostTask( | |
332 FROM_HERE, | |
333 base::Bind(&AppendToVectorTestTask, &order, std::string("D2"))); | |
334 compositor_task_runner_->PostTask( | |
335 FROM_HERE, | |
336 base::Bind(&AppendToVectorTestTask, &order, std::string("C2"))); | |
337 | |
338 // Compositor policy mode should have ended now that the clock has advanced. | |
339 RunUntilIdle(); | |
340 EXPECT_THAT(order, | |
341 testing::ElementsAre(std::string("D1"), | |
342 std::string("C1"), | |
343 std::string("D2"), | |
344 std::string("C2"))); | |
345 } | |
346 | |
347 } // namespace content | |
OLD | NEW |