Deleting the forwarding header files base/debug/trace_event*
[chromium-blink-merge.git] / content / renderer / scheduler / renderer_scheduler_impl_unittest.cc
blob36c85d3cf698afa5e30ae98609ae864efea56d30
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.
5 #include "content/renderer/scheduler/renderer_scheduler_impl.h"
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"
13 namespace content {
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 {}
23 protected:
24 base::TimeTicks Now() const override { return clock_->Now(); }
26 private:
27 scoped_refptr<cc::TestNowSource> clock_;
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 loading_task_runner_(scheduler_->LoadingTaskRunner()),
39 idle_task_runner_(scheduler_->IdleTaskRunner()) {}
40 ~RendererSchedulerImplTest() override {}
42 void RunUntilIdle() { mock_task_runner_->RunUntilIdle(); }
44 void EnableIdleTasks() {
45 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
46 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
47 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
48 scheduler_->DidCommitFrameToCompositor();
51 protected:
52 scoped_refptr<cc::TestNowSource> clock_;
53 scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
55 scoped_ptr<RendererSchedulerImpl> scheduler_;
56 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
57 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
58 scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_;
59 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
61 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImplTest);
64 void NullTask() {
67 void OrderedTestTask(int value, int* result) {
68 *result = (*result << 4) | value;
71 void UnorderedTestTask(int value, int* result) {
72 *result += value;
75 void AppendToVectorTestTask(std::vector<std::string>* vector,
76 std::string value) {
77 vector->push_back(value);
80 void AppendToVectorIdleTestTask(std::vector<std::string>* vector,
81 std::string value,
82 base::TimeTicks deadline) {
83 AppendToVectorTestTask(vector, value);
86 void AppendToVectorReentrantTask(
87 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
88 std::vector<int>* vector,
89 int* reentrant_count,
90 int max_reentrant_count) {
91 vector->push_back((*reentrant_count)++);
92 if (*reentrant_count < max_reentrant_count) {
93 task_runner->PostTask(
94 FROM_HERE, base::Bind(AppendToVectorReentrantTask, task_runner, vector,
95 reentrant_count, max_reentrant_count));
99 void IdleTestTask(bool* task_run,
100 base::TimeTicks* deadline_out,
101 base::TimeTicks deadline) {
102 EXPECT_FALSE(*task_run);
103 *deadline_out = deadline;
104 *task_run = true;
107 void RepostingIdleTestTask(
108 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner,
109 int* run_count,
110 base::TimeTicks deadline) {
111 if (*run_count == 0) {
112 idle_task_runner->PostIdleTask(
113 FROM_HERE,
114 base::Bind(&RepostingIdleTestTask, idle_task_runner, run_count));
116 (*run_count)++;
119 void UpdateClockToDeadlineIdleTestTask(
120 scoped_refptr<cc::TestNowSource> clock,
121 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
122 int* run_count,
123 base::TimeTicks deadline) {
124 clock->SetNow(deadline);
125 // Due to the way in which OrderedSimpleTestRunner orders tasks and the fact
126 // that we updated the time within a task, the delayed pending task to call
127 // EndIdlePeriod will not happen until after a TaskQueueManager DoWork, so
128 // post a normal task here to ensure it runs before the next idle task.
129 task_runner->PostTask(FROM_HERE, base::Bind(NullTask));
130 (*run_count)++;
133 void PostingYieldingTestTask(
134 RendererSchedulerImpl* scheduler,
135 scoped_refptr<base::SingleThreadTaskRunner> task_runner,
136 bool simulate_input,
137 bool* should_yield_before,
138 bool* should_yield_after) {
139 *should_yield_before = scheduler->ShouldYieldForHighPriorityWork();
140 task_runner->PostTask(FROM_HERE, base::Bind(NullTask));
141 if (simulate_input) {
142 scheduler->DidReceiveInputEventOnCompositorThread(
143 blink::WebInputEvent::GestureFlingStart);
145 *should_yield_after = scheduler->ShouldYieldForHighPriorityWork();
148 TEST_F(RendererSchedulerImplTest, TestPostDefaultTask) {
149 int result = 0;
150 default_task_runner_->PostTask(FROM_HERE,
151 base::Bind(OrderedTestTask, 1, &result));
152 default_task_runner_->PostTask(FROM_HERE,
153 base::Bind(OrderedTestTask, 2, &result));
154 default_task_runner_->PostTask(FROM_HERE,
155 base::Bind(OrderedTestTask, 3, &result));
156 default_task_runner_->PostTask(FROM_HERE,
157 base::Bind(OrderedTestTask, 4, &result));
158 RunUntilIdle();
159 EXPECT_EQ(0x1234, result);
162 TEST_F(RendererSchedulerImplTest, TestPostDefaultAndCompositor) {
163 int result = 0;
164 default_task_runner_->PostTask(FROM_HERE,
165 base::Bind(&UnorderedTestTask, 1, &result));
166 compositor_task_runner_->PostTask(FROM_HERE,
167 base::Bind(&UnorderedTestTask, 2, &result));
168 RunUntilIdle();
169 EXPECT_EQ(3, result);
172 TEST_F(RendererSchedulerImplTest, TestRentrantTask) {
173 int count = 0;
174 std::vector<int> order;
175 default_task_runner_->PostTask(
176 FROM_HERE, base::Bind(AppendToVectorReentrantTask, default_task_runner_,
177 &order, &count, 5));
178 RunUntilIdle();
180 EXPECT_THAT(order, testing::ElementsAre(0, 1, 2, 3, 4));
183 TEST_F(RendererSchedulerImplTest, TestPostIdleTask) {
184 bool task_run = false;
185 base::TimeTicks expected_deadline =
186 clock_->Now() + base::TimeDelta::FromMilliseconds(2300);
187 base::TimeTicks deadline_in_task;
189 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(100));
190 idle_task_runner_->PostIdleTask(
191 FROM_HERE, base::Bind(&IdleTestTask, &task_run, &deadline_in_task));
193 RunUntilIdle();
194 EXPECT_FALSE(task_run); // Shouldn't run yet as no WillBeginFrame.
196 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
197 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
198 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
199 RunUntilIdle();
200 EXPECT_FALSE(task_run); // Shouldn't run as no DidCommitFrameToCompositor.
202 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(1200));
203 scheduler_->DidCommitFrameToCompositor();
204 RunUntilIdle();
205 EXPECT_FALSE(task_run); // We missed the deadline.
207 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
208 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
209 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
210 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(800));
211 scheduler_->DidCommitFrameToCompositor();
212 RunUntilIdle();
213 EXPECT_TRUE(task_run);
214 EXPECT_EQ(expected_deadline, deadline_in_task);
217 TEST_F(RendererSchedulerImplTest, TestRepostingIdleTask) {
218 int run_count = 0;
220 idle_task_runner_->PostIdleTask(
221 FROM_HERE,
222 base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
223 EnableIdleTasks();
224 RunUntilIdle();
225 EXPECT_EQ(1, run_count);
227 // Reposted tasks shouldn't run until next idle period.
228 RunUntilIdle();
229 EXPECT_EQ(1, run_count);
231 EnableIdleTasks();
232 RunUntilIdle();
233 EXPECT_EQ(2, run_count);
236 TEST_F(RendererSchedulerImplTest, TestIdleTaskExceedsDeadline) {
237 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
238 int run_count = 0;
240 // Post two UpdateClockToDeadlineIdleTestTask tasks.
241 idle_task_runner_->PostIdleTask(
242 FROM_HERE, base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_,
243 default_task_runner_, &run_count));
244 idle_task_runner_->PostIdleTask(
245 FROM_HERE, base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_,
246 default_task_runner_, &run_count));
248 EnableIdleTasks();
249 RunUntilIdle();
250 // Only the first idle task should execute since it's used up the deadline.
251 EXPECT_EQ(1, run_count);
253 EnableIdleTasks();
254 RunUntilIdle();
255 // Second task should be run on the next idle period.
256 EXPECT_EQ(2, run_count);
259 TEST_F(RendererSchedulerImplTest, TestDelayedEndIdlePeriodCanceled) {
260 bool task_run = false;
262 base::TimeTicks deadline_in_task;
263 idle_task_runner_->PostIdleTask(
264 FROM_HERE, base::Bind(&IdleTestTask, &task_run, &deadline_in_task));
266 // Trigger the beginning of an idle period for 1000ms.
267 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
268 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
269 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
270 scheduler_->DidCommitFrameToCompositor();
272 // End the idle period early (after 500ms), and send a WillBeginFrame which
273 // specifies that the next idle period should end 1000ms from now.
274 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(500));
275 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
276 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
277 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
279 RunUntilIdle();
280 EXPECT_FALSE(task_run); // Not currently in an idle period.
282 // Trigger the start of the idle period before the task to end the previous
283 // idle period has been triggered.
284 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(400));
285 scheduler_->DidCommitFrameToCompositor();
287 // Post a task which simulates running until after the previous end idle
288 // period delayed task was scheduled for
289 scheduler_->DefaultTaskRunner()->PostTask(FROM_HERE, base::Bind(NullTask));
290 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(300));
292 RunUntilIdle();
293 EXPECT_TRUE(task_run); // We should still be in the new idle period.
296 TEST_F(RendererSchedulerImplTest, TestDefaultPolicy) {
297 std::vector<std::string> order;
299 loading_task_runner_->PostTask(
300 FROM_HERE,
301 base::Bind(&AppendToVectorTestTask, &order, std::string("L1")));
302 idle_task_runner_->PostIdleTask(
303 FROM_HERE,
304 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("I1")));
305 default_task_runner_->PostTask(
306 FROM_HERE,
307 base::Bind(&AppendToVectorTestTask, &order, std::string("D1")));
308 compositor_task_runner_->PostTask(
309 FROM_HERE,
310 base::Bind(&AppendToVectorTestTask, &order, std::string("C1")));
311 default_task_runner_->PostTask(
312 FROM_HERE,
313 base::Bind(&AppendToVectorTestTask, &order, std::string("D2")));
314 compositor_task_runner_->PostTask(
315 FROM_HERE,
316 base::Bind(&AppendToVectorTestTask, &order, std::string("C2")));
318 EnableIdleTasks();
319 RunUntilIdle();
320 EXPECT_THAT(order, testing::ElementsAre(
321 std::string("L1"), std::string("D1"), std::string("C1"),
322 std::string("D2"), std::string("C2"), std::string("I1")));
325 TEST_F(RendererSchedulerImplTest, TestCompositorPolicy) {
326 std::vector<std::string> order;
328 loading_task_runner_->PostTask(
329 FROM_HERE,
330 base::Bind(&AppendToVectorTestTask, &order, std::string("L1")));
331 idle_task_runner_->PostIdleTask(
332 FROM_HERE,
333 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("I1")));
334 default_task_runner_->PostTask(
335 FROM_HERE,
336 base::Bind(&AppendToVectorTestTask, &order, std::string("D1")));
337 compositor_task_runner_->PostTask(
338 FROM_HERE,
339 base::Bind(&AppendToVectorTestTask, &order, std::string("C1")));
340 default_task_runner_->PostTask(
341 FROM_HERE,
342 base::Bind(&AppendToVectorTestTask, &order, std::string("D2")));
343 compositor_task_runner_->PostTask(
344 FROM_HERE,
345 base::Bind(&AppendToVectorTestTask, &order, std::string("C2")));
347 scheduler_->DidReceiveInputEventOnCompositorThread(
348 blink::WebInputEvent::GestureFlingStart);
349 EnableIdleTasks();
350 RunUntilIdle();
351 EXPECT_THAT(order, testing::ElementsAre(
352 std::string("C1"), std::string("C2"), std::string("D1"),
353 std::string("D2"), std::string("L1"), std::string("I1")));
356 TEST_F(RendererSchedulerImplTest, TestCompositorPolicy_DidAnimateForInput) {
357 std::vector<std::string> order;
359 idle_task_runner_->PostIdleTask(
360 FROM_HERE,
361 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("I1")));
362 default_task_runner_->PostTask(
363 FROM_HERE,
364 base::Bind(&AppendToVectorTestTask, &order, std::string("D1")));
365 compositor_task_runner_->PostTask(
366 FROM_HERE,
367 base::Bind(&AppendToVectorTestTask, &order, std::string("C1")));
368 default_task_runner_->PostTask(
369 FROM_HERE,
370 base::Bind(&AppendToVectorTestTask, &order, std::string("D2")));
371 compositor_task_runner_->PostTask(
372 FROM_HERE,
373 base::Bind(&AppendToVectorTestTask, &order, std::string("C2")));
375 scheduler_->DidAnimateForInputOnCompositorThread();
376 EnableIdleTasks();
377 RunUntilIdle();
378 EXPECT_THAT(order, testing::ElementsAre(std::string("C1"), std::string("C2"),
379 std::string("D1"), std::string("D2"),
380 std::string("I1")));
383 TEST_F(RendererSchedulerImplTest,
384 DidReceiveInputEventOnCompositorThread_IgnoresMouseEvents) {
385 std::vector<std::string> order;
387 idle_task_runner_->PostIdleTask(
388 FROM_HERE,
389 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("I1")));
390 default_task_runner_->PostTask(
391 FROM_HERE,
392 base::Bind(&AppendToVectorTestTask, &order, std::string("D1")));
393 compositor_task_runner_->PostTask(
394 FROM_HERE,
395 base::Bind(&AppendToVectorTestTask, &order, std::string("C1")));
396 default_task_runner_->PostTask(
397 FROM_HERE,
398 base::Bind(&AppendToVectorTestTask, &order, std::string("D2")));
399 compositor_task_runner_->PostTask(
400 FROM_HERE,
401 base::Bind(&AppendToVectorTestTask, &order, std::string("C2")));
403 scheduler_->DidReceiveInputEventOnCompositorThread(
404 blink::WebInputEvent::MouseMove);
405 EnableIdleTasks();
406 RunUntilIdle();
407 // Note compositor tasks are not prioritized.
408 EXPECT_THAT(order, testing::ElementsAre(std::string("D1"), std::string("C1"),
409 std::string("D2"), std::string("C2"),
410 std::string("I1")));
413 TEST_F(RendererSchedulerImplTest,
414 DidReceiveInputEventOnCompositorThread_IgnoresKeyboardEvents) {
415 std::vector<std::string> order;
417 idle_task_runner_->PostIdleTask(
418 FROM_HERE,
419 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("I1")));
420 default_task_runner_->PostTask(
421 FROM_HERE,
422 base::Bind(&AppendToVectorTestTask, &order, std::string("D1")));
423 compositor_task_runner_->PostTask(
424 FROM_HERE,
425 base::Bind(&AppendToVectorTestTask, &order, std::string("C1")));
426 default_task_runner_->PostTask(
427 FROM_HERE,
428 base::Bind(&AppendToVectorTestTask, &order, std::string("D2")));
429 compositor_task_runner_->PostTask(
430 FROM_HERE,
431 base::Bind(&AppendToVectorTestTask, &order, std::string("C2")));
433 scheduler_->DidReceiveInputEventOnCompositorThread(
434 blink::WebInputEvent::KeyDown);
435 EnableIdleTasks();
436 RunUntilIdle();
437 // Note compositor tasks are not prioritized.
438 EXPECT_THAT(order, testing::ElementsAre(std::string("D1"), std::string("C1"),
439 std::string("D2"), std::string("C2"),
440 std::string("I1")));
443 TEST_F(RendererSchedulerImplTest,
444 TestCompositorPolicyDoesNotStarveDefaultTasks) {
445 std::vector<std::string> order;
447 default_task_runner_->PostTask(
448 FROM_HERE,
449 base::Bind(&AppendToVectorTestTask, &order, std::string("D1")));
450 compositor_task_runner_->PostTask(
451 FROM_HERE,
452 base::Bind(&AppendToVectorTestTask, &order, std::string("C1")));
453 for (int i = 0; i < 20; i++) {
454 compositor_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
456 compositor_task_runner_->PostTask(
457 FROM_HERE,
458 base::Bind(&AppendToVectorTestTask, &order, std::string("C2")));
460 scheduler_->DidReceiveInputEventOnCompositorThread(
461 blink::WebInputEvent::GestureFlingStart);
462 RunUntilIdle();
463 // Ensure that the default D1 task gets to run at some point before the final
464 // C2 compositor task.
465 EXPECT_THAT(order, testing::ElementsAre(std::string("C1"), std::string("D1"),
466 std::string("C2")));
469 TEST_F(RendererSchedulerImplTest, TestCompositorPolicyEnds) {
470 std::vector<std::string> order;
472 default_task_runner_->PostTask(
473 FROM_HERE,
474 base::Bind(&AppendToVectorTestTask, &order, std::string("D1")));
475 compositor_task_runner_->PostTask(
476 FROM_HERE,
477 base::Bind(&AppendToVectorTestTask, &order, std::string("C1")));
478 default_task_runner_->PostTask(
479 FROM_HERE,
480 base::Bind(&AppendToVectorTestTask, &order, std::string("D2")));
481 compositor_task_runner_->PostTask(
482 FROM_HERE,
483 base::Bind(&AppendToVectorTestTask, &order, std::string("C2")));
485 scheduler_->DidReceiveInputEventOnCompositorThread(
486 blink::WebInputEvent::GestureFlingStart);
487 RunUntilIdle();
488 EXPECT_THAT(order,
489 testing::ElementsAre(std::string("C1"), std::string("C2"),
490 std::string("D1"), std::string("D2")));
492 order.clear();
493 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(1000));
495 default_task_runner_->PostTask(
496 FROM_HERE,
497 base::Bind(&AppendToVectorTestTask, &order, std::string("D1")));
498 compositor_task_runner_->PostTask(
499 FROM_HERE,
500 base::Bind(&AppendToVectorTestTask, &order, std::string("C1")));
501 default_task_runner_->PostTask(
502 FROM_HERE,
503 base::Bind(&AppendToVectorTestTask, &order, std::string("D2")));
504 compositor_task_runner_->PostTask(
505 FROM_HERE,
506 base::Bind(&AppendToVectorTestTask, &order, std::string("C2")));
508 // Compositor policy mode should have ended now that the clock has advanced.
509 RunUntilIdle();
510 EXPECT_THAT(order,
511 testing::ElementsAre(std::string("D1"), std::string("C1"),
512 std::string("D2"), std::string("C2")));
515 TEST_F(RendererSchedulerImplTest, TestShouldYield) {
516 bool should_yield_before = false;
517 bool should_yield_after = false;
519 default_task_runner_->PostTask(
520 FROM_HERE, base::Bind(&PostingYieldingTestTask, scheduler_.get(),
521 default_task_runner_, false, &should_yield_before,
522 &should_yield_after));
523 RunUntilIdle();
524 // Posting to default runner shouldn't cause yielding.
525 EXPECT_FALSE(should_yield_before);
526 EXPECT_FALSE(should_yield_after);
528 default_task_runner_->PostTask(
529 FROM_HERE, base::Bind(&PostingYieldingTestTask, scheduler_.get(),
530 compositor_task_runner_, false,
531 &should_yield_before, &should_yield_after));
532 RunUntilIdle();
533 // Posting while not in compositor priority shouldn't cause yielding.
534 EXPECT_FALSE(should_yield_before);
535 EXPECT_FALSE(should_yield_after);
537 default_task_runner_->PostTask(
538 FROM_HERE, base::Bind(&PostingYieldingTestTask, scheduler_.get(),
539 compositor_task_runner_, true, &should_yield_before,
540 &should_yield_after));
541 RunUntilIdle();
542 // We should be able to switch to compositor priority mid-task.
543 EXPECT_FALSE(should_yield_before);
544 EXPECT_TRUE(should_yield_after);
547 } // namespace content