Move blink scheduler implementation into a component
[chromium-blink-merge.git] / components / scheduler / renderer / renderer_scheduler_impl_unittest.cc
blob27ec4319c2beb2077106ea6f642cdbb1497e113a
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 "components/scheduler/renderer/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 "cc/test/test_now_source.h"
11 #include "components/scheduler/child/nestable_task_runner_for_test.h"
12 #include "components/scheduler/child/scheduler_message_loop_delegate.h"
13 #include "components/scheduler/child/test_time_source.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
17 namespace scheduler {
19 namespace {
20 class FakeInputEvent : public blink::WebInputEvent {
21 public:
22 explicit FakeInputEvent(blink::WebInputEvent::Type event_type)
23 : WebInputEvent(sizeof(FakeInputEvent)) {
24 type = event_type;
27 FakeInputEvent(blink::WebInputEvent::Type event_type, int event_modifiers)
28 : WebInputEvent(sizeof(FakeInputEvent)) {
29 type = event_type;
30 modifiers = event_modifiers;
34 void AppendToVectorTestTask(std::vector<std::string>* vector,
35 std::string value) {
36 vector->push_back(value);
39 void AppendToVectorIdleTestTask(std::vector<std::string>* vector,
40 std::string value,
41 base::TimeTicks deadline) {
42 AppendToVectorTestTask(vector, value);
45 void NullTask() {
48 void AppendToVectorReentrantTask(base::SingleThreadTaskRunner* task_runner,
49 std::vector<int>* vector,
50 int* reentrant_count,
51 int max_reentrant_count) {
52 vector->push_back((*reentrant_count)++);
53 if (*reentrant_count < max_reentrant_count) {
54 task_runner->PostTask(
55 FROM_HERE,
56 base::Bind(AppendToVectorReentrantTask, base::Unretained(task_runner),
57 vector, reentrant_count, max_reentrant_count));
61 void IdleTestTask(int* run_count,
62 base::TimeTicks* deadline_out,
63 base::TimeTicks deadline) {
64 (*run_count)++;
65 *deadline_out = deadline;
68 int max_idle_task_reposts = 2;
70 void RepostingIdleTestTask(SingleThreadIdleTaskRunner* idle_task_runner,
71 int* run_count,
72 base::TimeTicks deadline) {
73 if ((*run_count + 1) < max_idle_task_reposts) {
74 idle_task_runner->PostIdleTask(
75 FROM_HERE, base::Bind(&RepostingIdleTestTask,
76 base::Unretained(idle_task_runner), run_count));
78 (*run_count)++;
81 void UpdateClockToDeadlineIdleTestTask(
82 cc::TestNowSource* clock,
83 base::SingleThreadTaskRunner* task_runner,
84 int* run_count,
85 base::TimeTicks deadline) {
86 clock->SetNow(deadline);
87 // Due to the way in which OrderedSimpleTestRunner orders tasks and the fact
88 // that we updated the time within a task, the delayed pending task to call
89 // EndIdlePeriod will not happen until after a TaskQueueManager DoWork, so
90 // post a normal task here to ensure it runs before the next idle task.
91 task_runner->PostTask(FROM_HERE, base::Bind(NullTask));
92 (*run_count)++;
95 void PostingYieldingTestTask(RendererSchedulerImpl* scheduler,
96 base::SingleThreadTaskRunner* task_runner,
97 bool simulate_input,
98 bool* should_yield_before,
99 bool* should_yield_after) {
100 *should_yield_before = scheduler->ShouldYieldForHighPriorityWork();
101 task_runner->PostTask(FROM_HERE, base::Bind(NullTask));
102 if (simulate_input) {
103 scheduler->DidReceiveInputEventOnCompositorThread(
104 FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
106 *should_yield_after = scheduler->ShouldYieldForHighPriorityWork();
109 void AnticipationTestTask(RendererSchedulerImpl* scheduler,
110 bool simulate_input,
111 bool* is_anticipated_before,
112 bool* is_anticipated_after) {
113 *is_anticipated_before = scheduler->IsHighPriorityWorkAnticipated();
114 if (simulate_input) {
115 scheduler->DidReceiveInputEventOnCompositorThread(
116 FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
118 *is_anticipated_after = scheduler->IsHighPriorityWorkAnticipated();
120 }; // namespace
122 class RendererSchedulerImplTest : public testing::Test {
123 public:
124 using Policy = RendererSchedulerImpl::Policy;
126 RendererSchedulerImplTest()
127 : clock_(cc::TestNowSource::Create(5000)),
128 mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_, false)),
129 nestable_task_runner_(
130 NestableTaskRunnerForTest::Create(mock_task_runner_)),
131 scheduler_(new RendererSchedulerImpl(nestable_task_runner_)),
132 default_task_runner_(scheduler_->DefaultTaskRunner()),
133 compositor_task_runner_(scheduler_->CompositorTaskRunner()),
134 loading_task_runner_(scheduler_->LoadingTaskRunner()),
135 idle_task_runner_(scheduler_->IdleTaskRunner()),
136 timer_task_runner_(scheduler_->TimerTaskRunner()) {
137 scheduler_->GetSchedulerHelperForTesting()->SetTimeSourceForTesting(
138 make_scoped_ptr(new TestTimeSource(clock_)));
139 scheduler_->GetSchedulerHelperForTesting()
140 ->GetTaskQueueManagerForTesting()
141 ->SetTimeSourceForTesting(make_scoped_ptr(new TestTimeSource(clock_)));
144 RendererSchedulerImplTest(base::MessageLoop* message_loop)
145 : clock_(cc::TestNowSource::Create(5000)),
146 message_loop_(message_loop),
147 nestable_task_runner_(
148 SchedulerMessageLoopDelegate::Create(message_loop)),
149 scheduler_(new RendererSchedulerImpl(nestable_task_runner_)),
150 default_task_runner_(scheduler_->DefaultTaskRunner()),
151 compositor_task_runner_(scheduler_->CompositorTaskRunner()),
152 loading_task_runner_(scheduler_->LoadingTaskRunner()),
153 idle_task_runner_(scheduler_->IdleTaskRunner()),
154 timer_task_runner_(scheduler_->TimerTaskRunner()) {
155 scheduler_->GetSchedulerHelperForTesting()->SetTimeSourceForTesting(
156 make_scoped_ptr(new TestTimeSource(clock_)));
157 scheduler_->GetSchedulerHelperForTesting()
158 ->GetTaskQueueManagerForTesting()
159 ->SetTimeSourceForTesting(make_scoped_ptr(new TestTimeSource(clock_)));
161 ~RendererSchedulerImplTest() override {}
163 void TearDown() override {
164 DCHECK(!mock_task_runner_.get() || !message_loop_.get());
165 if (mock_task_runner_.get()) {
166 // Check that all tests stop posting tasks.
167 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
168 while (mock_task_runner_->RunUntilIdle()) {
170 } else {
171 message_loop_->RunUntilIdle();
175 void RunUntilIdle() {
176 // Only one of mock_task_runner_ or message_loop_ should be set.
177 DCHECK(!mock_task_runner_.get() || !message_loop_.get());
178 if (mock_task_runner_.get())
179 mock_task_runner_->RunUntilIdle();
180 else
181 message_loop_->RunUntilIdle();
184 void DoMainFrame() {
185 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
186 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
187 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
188 scheduler_->DidCommitFrameToCompositor();
191 void EnableIdleTasks() { DoMainFrame(); }
193 Policy CurrentPolicy() { return scheduler_->current_policy_; }
195 void EnsureUrgentPolicyUpdatePostedOnMainThread() {
196 base::AutoLock lock(scheduler_->incoming_signals_lock_);
197 scheduler_->EnsureUrgentPolicyUpdatePostedOnMainThread(FROM_HERE);
200 void ScheduleDelayedPolicyUpdate(base::TimeDelta delay) {
201 scheduler_->delayed_update_policy_runner_.SetDeadline(FROM_HERE, delay,
202 clock_->Now());
205 // Helper for posting several tasks of specific types. |task_descriptor| is a
206 // string with space delimited task identifiers. The first letter of each
207 // task identifier specifies the task type:
208 // - 'D': Default task
209 // - 'C': Compositor task
210 // - 'L': Loading task
211 // - 'I': Idle task
212 // - 'T': Timer task
213 void PostTestTasks(std::vector<std::string>* run_order,
214 const std::string& task_descriptor) {
215 std::istringstream stream(task_descriptor);
216 while (!stream.eof()) {
217 std::string task;
218 stream >> task;
219 switch (task[0]) {
220 case 'D':
221 default_task_runner_->PostTask(
222 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task));
223 break;
224 case 'C':
225 compositor_task_runner_->PostTask(
226 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task));
227 break;
228 case 'L':
229 loading_task_runner_->PostTask(
230 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task));
231 break;
232 case 'I':
233 idle_task_runner_->PostIdleTask(
234 FROM_HERE,
235 base::Bind(&AppendToVectorIdleTestTask, run_order, task));
236 break;
237 case 'T':
238 timer_task_runner_->PostTask(
239 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task));
240 break;
241 default:
242 NOTREACHED();
247 protected:
248 static base::TimeDelta priority_escalation_after_input_duration() {
249 return base::TimeDelta::FromMilliseconds(
250 RendererSchedulerImpl::kPriorityEscalationAfterInputMillis);
253 static base::TimeDelta maximum_idle_period_duration() {
254 return base::TimeDelta::FromMilliseconds(
255 SchedulerHelper::kMaximumIdlePeriodMillis);
258 static base::TimeDelta end_idle_when_hidden_delay() {
259 return base::TimeDelta::FromMilliseconds(
260 RendererSchedulerImpl::kEndIdleWhenHiddenDelayMillis);
263 scoped_refptr<cc::TestNowSource> clock_;
264 // Only one of mock_task_runner_ or message_loop_ will be set.
265 scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
266 scoped_ptr<base::MessageLoop> message_loop_;
268 scoped_refptr<NestableSingleThreadTaskRunner> nestable_task_runner_;
269 scoped_ptr<RendererSchedulerImpl> scheduler_;
270 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
271 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
272 scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_;
273 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
274 scoped_refptr<base::SingleThreadTaskRunner> timer_task_runner_;
276 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImplTest);
279 TEST_F(RendererSchedulerImplTest, TestPostDefaultTask) {
280 std::vector<std::string> run_order;
281 PostTestTasks(&run_order, "D1 D2 D3 D4");
283 RunUntilIdle();
284 EXPECT_THAT(run_order,
285 testing::ElementsAre(std::string("D1"), std::string("D2"),
286 std::string("D3"), std::string("D4")));
289 TEST_F(RendererSchedulerImplTest, TestPostDefaultAndCompositor) {
290 std::vector<std::string> run_order;
291 PostTestTasks(&run_order, "D1 C1");
292 RunUntilIdle();
293 EXPECT_THAT(run_order, testing::Contains("D1"));
294 EXPECT_THAT(run_order, testing::Contains("C1"));
297 TEST_F(RendererSchedulerImplTest, TestRentrantTask) {
298 int count = 0;
299 std::vector<int> run_order;
300 default_task_runner_->PostTask(
301 FROM_HERE, base::Bind(AppendToVectorReentrantTask, default_task_runner_,
302 &run_order, &count, 5));
303 RunUntilIdle();
305 EXPECT_THAT(run_order, testing::ElementsAre(0, 1, 2, 3, 4));
308 TEST_F(RendererSchedulerImplTest, TestPostIdleTask) {
309 int run_count = 0;
310 base::TimeTicks expected_deadline =
311 clock_->Now() + base::TimeDelta::FromMilliseconds(2300);
312 base::TimeTicks deadline_in_task;
314 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(100));
315 idle_task_runner_->PostIdleTask(
316 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
318 RunUntilIdle();
319 EXPECT_EQ(0, run_count); // Shouldn't run yet as no WillBeginFrame.
321 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
322 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
323 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
324 RunUntilIdle();
325 EXPECT_EQ(0, run_count); // Shouldn't run as no DidCommitFrameToCompositor.
327 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(1200));
328 scheduler_->DidCommitFrameToCompositor();
329 RunUntilIdle();
330 EXPECT_EQ(0, run_count); // We missed the deadline.
332 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
333 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
334 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
335 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(800));
336 scheduler_->DidCommitFrameToCompositor();
337 RunUntilIdle();
338 EXPECT_EQ(1, run_count);
339 EXPECT_EQ(expected_deadline, deadline_in_task);
342 TEST_F(RendererSchedulerImplTest, TestRepostingIdleTask) {
343 int run_count = 0;
345 max_idle_task_reposts = 2;
346 idle_task_runner_->PostIdleTask(
347 FROM_HERE,
348 base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
349 EnableIdleTasks();
350 RunUntilIdle();
351 EXPECT_EQ(1, run_count);
353 // Reposted tasks shouldn't run until next idle period.
354 RunUntilIdle();
355 EXPECT_EQ(1, run_count);
357 EnableIdleTasks();
358 RunUntilIdle();
359 EXPECT_EQ(2, run_count);
362 TEST_F(RendererSchedulerImplTest, TestIdleTaskExceedsDeadline) {
363 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
364 int run_count = 0;
366 // Post two UpdateClockToDeadlineIdleTestTask tasks.
367 idle_task_runner_->PostIdleTask(
368 FROM_HERE, base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_,
369 default_task_runner_, &run_count));
370 idle_task_runner_->PostIdleTask(
371 FROM_HERE, base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_,
372 default_task_runner_, &run_count));
374 EnableIdleTasks();
375 RunUntilIdle();
376 // Only the first idle task should execute since it's used up the deadline.
377 EXPECT_EQ(1, run_count);
379 EnableIdleTasks();
380 RunUntilIdle();
381 // Second task should be run on the next idle period.
382 EXPECT_EQ(2, run_count);
385 TEST_F(RendererSchedulerImplTest, TestPostIdleTaskAfterWakeup) {
386 base::TimeTicks deadline_in_task;
387 int run_count = 0;
389 idle_task_runner_->PostIdleTaskAfterWakeup(
390 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
392 EnableIdleTasks();
393 RunUntilIdle();
394 // Shouldn't run yet as no other task woke up the scheduler.
395 EXPECT_EQ(0, run_count);
397 idle_task_runner_->PostIdleTaskAfterWakeup(
398 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
400 EnableIdleTasks();
401 RunUntilIdle();
402 // Another after wakeup idle task shouldn't wake the scheduler.
403 EXPECT_EQ(0, run_count);
405 default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
407 RunUntilIdle();
408 EnableIdleTasks(); // Must start a new idle period before idle task runs.
409 RunUntilIdle();
410 // Execution of default task queue task should trigger execution of idle task.
411 EXPECT_EQ(2, run_count);
414 TEST_F(RendererSchedulerImplTest, TestPostIdleTaskAfterWakeupWhileAwake) {
415 base::TimeTicks deadline_in_task;
416 int run_count = 0;
418 idle_task_runner_->PostIdleTaskAfterWakeup(
419 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
420 default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
422 RunUntilIdle();
423 EnableIdleTasks(); // Must start a new idle period before idle task runs.
424 RunUntilIdle();
425 // Should run as the scheduler was already awakened by the normal task.
426 EXPECT_EQ(1, run_count);
429 TEST_F(RendererSchedulerImplTest, TestPostIdleTaskWakesAfterWakeupIdleTask) {
430 base::TimeTicks deadline_in_task;
431 int run_count = 0;
433 idle_task_runner_->PostIdleTaskAfterWakeup(
434 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
435 idle_task_runner_->PostIdleTask(
436 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
438 EnableIdleTasks();
439 RunUntilIdle();
440 // Must start a new idle period before after-wakeup idle task runs.
441 EnableIdleTasks();
442 RunUntilIdle();
443 // Normal idle task should wake up after-wakeup idle task.
444 EXPECT_EQ(2, run_count);
447 TEST_F(RendererSchedulerImplTest, TestDelayedEndIdlePeriodCanceled) {
448 int run_count = 0;
450 base::TimeTicks deadline_in_task;
451 idle_task_runner_->PostIdleTask(
452 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
454 // Trigger the beginning of an idle period for 1000ms.
455 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
456 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
457 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
458 DoMainFrame();
460 // End the idle period early (after 500ms), and send a WillBeginFrame which
461 // specifies that the next idle period should end 1000ms from now.
462 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(500));
463 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
464 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
465 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
467 RunUntilIdle();
468 EXPECT_EQ(0, run_count); // Not currently in an idle period.
470 // Trigger the start of the idle period before the task to end the previous
471 // idle period has been triggered.
472 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(400));
473 scheduler_->DidCommitFrameToCompositor();
475 // Post a task which simulates running until after the previous end idle
476 // period delayed task was scheduled for
477 scheduler_->DefaultTaskRunner()->PostTask(FROM_HERE, base::Bind(NullTask));
478 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(300));
480 RunUntilIdle();
481 EXPECT_EQ(1, run_count); // We should still be in the new idle period.
484 TEST_F(RendererSchedulerImplTest, TestDefaultPolicy) {
485 std::vector<std::string> run_order;
486 PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
488 EnableIdleTasks();
489 RunUntilIdle();
490 EXPECT_THAT(run_order,
491 testing::ElementsAre(std::string("L1"), std::string("D1"),
492 std::string("C1"), std::string("D2"),
493 std::string("C2"), std::string("I1")));
496 TEST_F(RendererSchedulerImplTest, TestCompositorPolicy) {
497 std::vector<std::string> run_order;
498 PostTestTasks(&run_order, "L1 I1 D1 C1 D2 C2");
500 scheduler_->DidReceiveInputEventOnCompositorThread(
501 FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
502 EnableIdleTasks();
503 RunUntilIdle();
504 EXPECT_THAT(run_order,
505 testing::ElementsAre(std::string("C1"), std::string("C2"),
506 std::string("D1"), std::string("D2"),
507 std::string("L1"), std::string("I1")));
510 TEST_F(RendererSchedulerImplTest, TestCompositorPolicy_DidAnimateForInput) {
511 std::vector<std::string> run_order;
512 PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
514 scheduler_->DidAnimateForInputOnCompositorThread();
515 EnableIdleTasks();
516 RunUntilIdle();
517 EXPECT_THAT(run_order,
518 testing::ElementsAre(std::string("C1"), std::string("C2"),
519 std::string("D1"), std::string("D2"),
520 std::string("I1")));
523 TEST_F(RendererSchedulerImplTest, TestTouchstartPolicy) {
524 std::vector<std::string> run_order;
525 PostTestTasks(&run_order, "L1 D1 C1 D2 C2 T1 T2");
527 // Observation of touchstart should defer execution of idle and loading tasks.
528 scheduler_->DidReceiveInputEventOnCompositorThread(
529 FakeInputEvent(blink::WebInputEvent::TouchStart));
530 RunUntilIdle();
531 EXPECT_THAT(run_order,
532 testing::ElementsAre(std::string("C1"), std::string("C2"),
533 std::string("D1"), std::string("D2"),
534 std::string("T1"), std::string("T2")));
536 // Meta events like TapDown/FlingCancel shouldn't affect the priority.
537 run_order.clear();
538 scheduler_->DidReceiveInputEventOnCompositorThread(
539 FakeInputEvent(blink::WebInputEvent::GestureFlingCancel));
540 scheduler_->DidReceiveInputEventOnCompositorThread(
541 FakeInputEvent(blink::WebInputEvent::GestureTapDown));
542 RunUntilIdle();
543 EXPECT_TRUE(run_order.empty());
545 // Action events like ScrollBegin will kick us back into compositor priority,
546 // allowing service of the timer, loading and idle queues.
547 run_order.clear();
548 scheduler_->DidReceiveInputEventOnCompositorThread(
549 FakeInputEvent(blink::WebInputEvent::GestureScrollBegin));
550 RunUntilIdle();
552 EXPECT_THAT(run_order, testing::ElementsAre(std::string("L1")));
555 TEST_F(RendererSchedulerImplTest,
556 DidReceiveInputEventOnCompositorThread_IgnoresMouseMove_WhenMouseUp) {
557 std::vector<std::string> run_order;
558 PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
560 scheduler_->DidReceiveInputEventOnCompositorThread(
561 FakeInputEvent(blink::WebInputEvent::MouseMove));
562 EnableIdleTasks();
563 RunUntilIdle();
564 // Note compositor tasks are not prioritized.
565 EXPECT_THAT(run_order,
566 testing::ElementsAre(std::string("D1"), std::string("C1"),
567 std::string("D2"), std::string("C2"),
568 std::string("I1")));
571 TEST_F(RendererSchedulerImplTest,
572 DidReceiveInputEventOnCompositorThread_MouseMove_WhenMouseDown) {
573 std::vector<std::string> run_order;
574 PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
576 scheduler_->DidReceiveInputEventOnCompositorThread(FakeInputEvent(
577 blink::WebInputEvent::MouseMove, blink::WebInputEvent::LeftButtonDown));
578 EnableIdleTasks();
579 RunUntilIdle();
580 // Note compositor tasks are prioritized.
581 EXPECT_THAT(run_order,
582 testing::ElementsAre(std::string("C1"), std::string("C2"),
583 std::string("D1"), std::string("D2"),
584 std::string("I1")));
587 TEST_F(RendererSchedulerImplTest,
588 DidReceiveInputEventOnCompositorThread_MouseWheel) {
589 std::vector<std::string> run_order;
590 PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
592 scheduler_->DidReceiveInputEventOnCompositorThread(
593 FakeInputEvent(blink::WebInputEvent::MouseWheel));
594 EnableIdleTasks();
595 RunUntilIdle();
596 // Note compositor tasks are prioritized.
597 EXPECT_THAT(run_order,
598 testing::ElementsAre(std::string("C1"), std::string("C2"),
599 std::string("D1"), std::string("D2"),
600 std::string("I1")));
603 TEST_F(RendererSchedulerImplTest,
604 DidReceiveInputEventOnCompositorThread_IgnoresKeyboardEvents) {
605 std::vector<std::string> run_order;
606 PostTestTasks(&run_order, "I1 D1 C1 D2 C2");
608 scheduler_->DidReceiveInputEventOnCompositorThread(
609 FakeInputEvent(blink::WebInputEvent::KeyDown));
610 EnableIdleTasks();
611 RunUntilIdle();
612 // Note compositor tasks are not prioritized.
613 EXPECT_THAT(run_order,
614 testing::ElementsAre(std::string("D1"), std::string("C1"),
615 std::string("D2"), std::string("C2"),
616 std::string("I1")));
619 TEST_F(RendererSchedulerImplTest,
620 TestCompositorPolicyDoesNotStarveDefaultTasks) {
621 std::vector<std::string> run_order;
622 PostTestTasks(&run_order, "D1 C1");
624 for (int i = 0; i < 20; i++) {
625 compositor_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
627 PostTestTasks(&run_order, "C2");
629 scheduler_->DidReceiveInputEventOnCompositorThread(
630 FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
631 RunUntilIdle();
632 // Ensure that the default D1 task gets to run at some point before the final
633 // C2 compositor task.
634 EXPECT_THAT(run_order,
635 testing::ElementsAre(std::string("C1"), std::string("D1"),
636 std::string("C2")));
639 TEST_F(RendererSchedulerImplTest, TestCompositorPolicyEnds) {
640 std::vector<std::string> run_order;
641 PostTestTasks(&run_order, "D1 C1 D2 C2");
643 scheduler_->DidReceiveInputEventOnCompositorThread(
644 FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
645 DoMainFrame();
646 RunUntilIdle();
647 EXPECT_THAT(run_order,
648 testing::ElementsAre(std::string("C1"), std::string("C2"),
649 std::string("D1"), std::string("D2")));
651 run_order.clear();
652 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(1000));
653 PostTestTasks(&run_order, "D1 C1 D2 C2");
655 // Compositor policy mode should have ended now that the clock has advanced.
656 RunUntilIdle();
657 EXPECT_THAT(run_order,
658 testing::ElementsAre(std::string("D1"), std::string("C1"),
659 std::string("D2"), std::string("C2")));
662 TEST_F(RendererSchedulerImplTest, TestTouchstartPolicyEndsAfterTimeout) {
663 std::vector<std::string> run_order;
664 PostTestTasks(&run_order, "L1 D1 C1 D2 C2");
666 scheduler_->DidReceiveInputEventOnCompositorThread(
667 FakeInputEvent(blink::WebInputEvent::TouchStart));
668 RunUntilIdle();
669 EXPECT_THAT(run_order,
670 testing::ElementsAre(std::string("C1"), std::string("C2"),
671 std::string("D1"), std::string("D2")));
673 run_order.clear();
674 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(1000));
676 // Don't post any compositor tasks to simulate a very long running event
677 // handler.
678 PostTestTasks(&run_order, "D1 D2");
680 // Touchstart policy mode should have ended now that the clock has advanced.
681 RunUntilIdle();
682 EXPECT_THAT(run_order,
683 testing::ElementsAre(std::string("L1"), std::string("D1"),
684 std::string("D2")));
687 TEST_F(RendererSchedulerImplTest,
688 TestTouchstartPolicyEndsAfterConsecutiveTouchmoves) {
689 std::vector<std::string> run_order;
690 PostTestTasks(&run_order, "L1 D1 C1 D2 C2");
692 // Observation of touchstart should defer execution of idle and loading tasks.
693 scheduler_->DidReceiveInputEventOnCompositorThread(
694 FakeInputEvent(blink::WebInputEvent::TouchStart));
695 DoMainFrame();
696 RunUntilIdle();
697 EXPECT_THAT(run_order,
698 testing::ElementsAre(std::string("C1"), std::string("C2"),
699 std::string("D1"), std::string("D2")));
701 // Receiving the first touchmove will not affect scheduler priority.
702 run_order.clear();
703 scheduler_->DidReceiveInputEventOnCompositorThread(
704 FakeInputEvent(blink::WebInputEvent::TouchMove));
705 DoMainFrame();
706 RunUntilIdle();
707 EXPECT_TRUE(run_order.empty());
709 // Receiving the second touchmove will kick us back into compositor priority.
710 run_order.clear();
711 scheduler_->DidReceiveInputEventOnCompositorThread(
712 FakeInputEvent(blink::WebInputEvent::TouchMove));
713 RunUntilIdle();
714 EXPECT_THAT(run_order, testing::ElementsAre(std::string("L1")));
717 TEST_F(RendererSchedulerImplTest, TestIsHighPriorityWorkAnticipated) {
718 bool is_anticipated_before = false;
719 bool is_anticipated_after = false;
721 bool simulate_input = false;
722 default_task_runner_->PostTask(
723 FROM_HERE,
724 base::Bind(&AnticipationTestTask, scheduler_.get(), simulate_input,
725 &is_anticipated_before, &is_anticipated_after));
726 RunUntilIdle();
727 // In its default state, without input receipt, the scheduler should indicate
728 // that no high-priority is anticipated.
729 EXPECT_FALSE(is_anticipated_before);
730 EXPECT_FALSE(is_anticipated_after);
732 simulate_input = true;
733 default_task_runner_->PostTask(
734 FROM_HERE,
735 base::Bind(&AnticipationTestTask, scheduler_.get(), simulate_input,
736 &is_anticipated_before, &is_anticipated_after));
737 RunUntilIdle();
738 // When input is received, the scheduler should indicate that high-priority
739 // work is anticipated.
740 EXPECT_FALSE(is_anticipated_before);
741 EXPECT_TRUE(is_anticipated_after);
743 clock_->AdvanceNow(priority_escalation_after_input_duration() * 2);
744 simulate_input = false;
745 default_task_runner_->PostTask(
746 FROM_HERE,
747 base::Bind(&AnticipationTestTask, scheduler_.get(), simulate_input,
748 &is_anticipated_before, &is_anticipated_after));
749 RunUntilIdle();
750 // Without additional input, the scheduler should indicate that high-priority
751 // work is no longer anticipated.
752 EXPECT_FALSE(is_anticipated_before);
753 EXPECT_FALSE(is_anticipated_after);
756 TEST_F(RendererSchedulerImplTest, TestShouldYield) {
757 bool should_yield_before = false;
758 bool should_yield_after = false;
760 default_task_runner_->PostTask(
761 FROM_HERE, base::Bind(&PostingYieldingTestTask, scheduler_.get(),
762 default_task_runner_, false, &should_yield_before,
763 &should_yield_after));
764 RunUntilIdle();
765 // Posting to default runner shouldn't cause yielding.
766 EXPECT_FALSE(should_yield_before);
767 EXPECT_FALSE(should_yield_after);
769 default_task_runner_->PostTask(
770 FROM_HERE, base::Bind(&PostingYieldingTestTask, scheduler_.get(),
771 compositor_task_runner_, false,
772 &should_yield_before, &should_yield_after));
773 RunUntilIdle();
774 // Posting while not in compositor priority shouldn't cause yielding.
775 EXPECT_FALSE(should_yield_before);
776 EXPECT_FALSE(should_yield_after);
778 default_task_runner_->PostTask(
779 FROM_HERE, base::Bind(&PostingYieldingTestTask, scheduler_.get(),
780 compositor_task_runner_, true, &should_yield_before,
781 &should_yield_after));
782 RunUntilIdle();
783 // We should be able to switch to compositor priority mid-task.
784 EXPECT_FALSE(should_yield_before);
785 EXPECT_TRUE(should_yield_after);
787 // Receiving a touchstart should immediately trigger yielding, even if
788 // there's no immediately pending work in the compositor queue.
789 EXPECT_FALSE(scheduler_->ShouldYieldForHighPriorityWork());
790 scheduler_->DidReceiveInputEventOnCompositorThread(
791 FakeInputEvent(blink::WebInputEvent::TouchStart));
792 EXPECT_TRUE(scheduler_->ShouldYieldForHighPriorityWork());
793 RunUntilIdle();
796 TEST_F(RendererSchedulerImplTest, SlowInputEvent) {
797 EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
799 // An input event should bump us into input priority.
800 scheduler_->DidReceiveInputEventOnCompositorThread(
801 FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
802 RunUntilIdle();
803 EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
805 // Simulate the input event being queued for a very long time. The compositor
806 // task we post here represents the enqueued input task.
807 clock_->AdvanceNow(priority_escalation_after_input_duration() * 2);
808 compositor_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
809 RunUntilIdle();
811 // Even though we exceeded the input priority escalation period, we should
812 // still be in compositor priority since the input remains queued.
813 EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
815 // Simulate the input event triggering a composition. This should start the
816 // countdown for going back into normal policy.
817 DoMainFrame();
818 RunUntilIdle();
819 EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
821 // After the escalation period ends we should go back into normal mode.
822 clock_->AdvanceNow(priority_escalation_after_input_duration() * 2);
823 RunUntilIdle();
824 EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
827 TEST_F(RendererSchedulerImplTest, SlowNoOpInputEvent) {
828 EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
830 // An input event should bump us into input priority.
831 scheduler_->DidReceiveInputEventOnCompositorThread(
832 FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
833 RunUntilIdle();
834 EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
836 // Simulate the input event being queued for a very long time. The compositor
837 // task we post here represents the enqueued input task.
838 clock_->AdvanceNow(priority_escalation_after_input_duration() * 2);
839 compositor_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
840 RunUntilIdle();
842 // Even though we exceeded the input priority escalation period, we should
843 // still be in compositor priority since the input remains queued.
844 EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
846 // If we let the compositor queue drain, we should fall out of input
847 // priority.
848 clock_->AdvanceNow(priority_escalation_after_input_duration() * 2);
849 RunUntilIdle();
850 EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
853 TEST_F(RendererSchedulerImplTest, NoOpInputEvent) {
854 EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
856 // An input event should bump us into input priority.
857 scheduler_->DidReceiveInputEventOnCompositorThread(
858 FakeInputEvent(blink::WebInputEvent::GestureFlingStart));
859 RunUntilIdle();
860 EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
862 // If nothing else happens after this, we should drop out of compositor
863 // priority after the escalation period ends and stop polling.
864 clock_->AdvanceNow(priority_escalation_after_input_duration() * 2);
865 RunUntilIdle();
866 EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
867 EXPECT_FALSE(mock_task_runner_->HasPendingTasks());
870 TEST_F(RendererSchedulerImplTest, NoOpInputEventExtendsEscalationPeriod) {
871 EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
873 // Simulate one handled input event.
874 scheduler_->DidReceiveInputEventOnCompositorThread(
875 FakeInputEvent(blink::WebInputEvent::GestureScrollBegin));
876 RunUntilIdle();
877 DoMainFrame();
878 EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
880 // Send a no-op input event in the middle of the escalation period.
881 clock_->AdvanceNow(priority_escalation_after_input_duration() / 2);
882 scheduler_->DidReceiveInputEventOnCompositorThread(
883 FakeInputEvent(blink::WebInputEvent::GestureScrollUpdate));
884 RunUntilIdle();
885 EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
887 // The escalation period should have been extended by the new input event.
888 clock_->AdvanceNow(3 * priority_escalation_after_input_duration() / 4);
889 RunUntilIdle();
890 EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
892 clock_->AdvanceNow(priority_escalation_after_input_duration() / 2);
893 RunUntilIdle();
894 EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
897 TEST_F(RendererSchedulerImplTest, InputArrivesAfterBeginFrame) {
898 EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
900 cc::BeginFrameArgs args = cc::BeginFrameArgs::Create(
901 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
902 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL);
903 clock_->AdvanceNow(priority_escalation_after_input_duration() / 2);
905 scheduler_->DidReceiveInputEventOnCompositorThread(
906 FakeInputEvent(blink::WebInputEvent::GestureScrollBegin));
908 // Simulate a BeginMainFrame task from the past.
909 clock_->AdvanceNow(2 * priority_escalation_after_input_duration());
910 scheduler_->WillBeginFrame(args);
911 scheduler_->DidCommitFrameToCompositor();
913 // This task represents the queued-up input event.
914 compositor_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
916 // Should remain in input priority policy since the input event hasn't been
917 // processed yet.
918 clock_->AdvanceNow(2 * priority_escalation_after_input_duration());
919 RunUntilIdle();
920 EXPECT_EQ(Policy::COMPOSITOR_PRIORITY, CurrentPolicy());
922 // Process the input event with a new BeginMainFrame.
923 DoMainFrame();
924 clock_->AdvanceNow(2 * priority_escalation_after_input_duration());
925 RunUntilIdle();
926 EXPECT_EQ(Policy::NORMAL, CurrentPolicy());
929 class RendererSchedulerImplForTest : public RendererSchedulerImpl {
930 public:
931 RendererSchedulerImplForTest(
932 scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner)
933 : RendererSchedulerImpl(main_task_runner), update_policy_count_(0) {}
935 void UpdatePolicyLocked(UpdateType update_type) override {
936 update_policy_count_++;
937 RendererSchedulerImpl::UpdatePolicyLocked(update_type);
940 int update_policy_count_;
943 TEST_F(RendererSchedulerImplTest, OnlyOnePendingUrgentPolicyUpdatey) {
944 RendererSchedulerImplForTest* mock_scheduler =
945 new RendererSchedulerImplForTest(nestable_task_runner_);
946 scheduler_.reset(mock_scheduler);
948 EnsureUrgentPolicyUpdatePostedOnMainThread();
949 EnsureUrgentPolicyUpdatePostedOnMainThread();
950 EnsureUrgentPolicyUpdatePostedOnMainThread();
951 EnsureUrgentPolicyUpdatePostedOnMainThread();
953 RunUntilIdle();
955 EXPECT_EQ(1, mock_scheduler->update_policy_count_);
958 TEST_F(RendererSchedulerImplTest, OnePendingDelayedAndOneUrgentUpdatePolicy) {
959 RendererSchedulerImplForTest* mock_scheduler =
960 new RendererSchedulerImplForTest(nestable_task_runner_);
961 scheduler_.reset(mock_scheduler);
962 scheduler_->GetSchedulerHelperForTesting()->SetTimeSourceForTesting(
963 make_scoped_ptr(new TestTimeSource(clock_)));
964 scheduler_->GetSchedulerHelperForTesting()
965 ->GetTaskQueueManagerForTesting()
966 ->SetTimeSourceForTesting(make_scoped_ptr(new TestTimeSource(clock_)));
967 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
969 ScheduleDelayedPolicyUpdate(base::TimeDelta::FromMilliseconds(1));
970 EnsureUrgentPolicyUpdatePostedOnMainThread();
972 RunUntilIdle();
974 // We expect both the urgent and the delayed updates to run.
975 EXPECT_EQ(2, mock_scheduler->update_policy_count_);
978 TEST_F(RendererSchedulerImplTest, OneUrgentAndOnePendingDelayedUpdatePolicy) {
979 RendererSchedulerImplForTest* mock_scheduler =
980 new RendererSchedulerImplForTest(nestable_task_runner_);
981 scheduler_.reset(mock_scheduler);
982 scheduler_->GetSchedulerHelperForTesting()->SetTimeSourceForTesting(
983 make_scoped_ptr(new TestTimeSource(clock_)));
984 scheduler_->GetSchedulerHelperForTesting()
985 ->GetTaskQueueManagerForTesting()
986 ->SetTimeSourceForTesting(make_scoped_ptr(new TestTimeSource(clock_)));
987 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
989 EnsureUrgentPolicyUpdatePostedOnMainThread();
990 ScheduleDelayedPolicyUpdate(base::TimeDelta::FromMilliseconds(1));
992 RunUntilIdle();
994 // We expect both the urgent and the delayed updates to run.
995 EXPECT_EQ(2, mock_scheduler->update_policy_count_);
998 TEST_F(RendererSchedulerImplTest, UpdatePolicyCountTriggeredByOneInputEvent) {
999 RendererSchedulerImplForTest* mock_scheduler =
1000 new RendererSchedulerImplForTest(nestable_task_runner_);
1001 scheduler_.reset(mock_scheduler);
1002 scheduler_->GetSchedulerHelperForTesting()->SetTimeSourceForTesting(
1003 make_scoped_ptr(new TestTimeSource(clock_)));
1004 scheduler_->GetSchedulerHelperForTesting()
1005 ->GetTaskQueueManagerForTesting()
1006 ->SetTimeSourceForTesting(make_scoped_ptr(new TestTimeSource(clock_)));
1007 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
1009 scheduler_->DidReceiveInputEventOnCompositorThread(
1010 FakeInputEvent(blink::WebInputEvent::TouchStart));
1012 RunUntilIdle();
1014 // We expect an urgent policy update followed by a delayed one 100ms later.
1015 EXPECT_EQ(2, mock_scheduler->update_policy_count_);
1018 TEST_F(RendererSchedulerImplTest, UpdatePolicyCountTriggeredByTwoInputEvents) {
1019 RendererSchedulerImplForTest* mock_scheduler =
1020 new RendererSchedulerImplForTest(nestable_task_runner_);
1021 scheduler_.reset(mock_scheduler);
1022 scheduler_->GetSchedulerHelperForTesting()->SetTimeSourceForTesting(
1023 make_scoped_ptr(new TestTimeSource(clock_)));
1024 scheduler_->GetSchedulerHelperForTesting()
1025 ->GetTaskQueueManagerForTesting()
1026 ->SetTimeSourceForTesting(make_scoped_ptr(new TestTimeSource(clock_)));
1027 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
1029 scheduler_->DidReceiveInputEventOnCompositorThread(
1030 FakeInputEvent(blink::WebInputEvent::TouchStart));
1031 scheduler_->DidReceiveInputEventOnCompositorThread(
1032 FakeInputEvent(blink::WebInputEvent::TouchMove));
1034 RunUntilIdle();
1036 // We expect an urgent policy update followed by a delayed one 100ms later.
1037 EXPECT_EQ(2, mock_scheduler->update_policy_count_);
1040 TEST_F(RendererSchedulerImplTest, EnsureUpdatePolicyNotTriggeredTooOften) {
1041 RendererSchedulerImplForTest* mock_scheduler =
1042 new RendererSchedulerImplForTest(nestable_task_runner_);
1043 scheduler_.reset(mock_scheduler);
1044 scheduler_->GetSchedulerHelperForTesting()->SetTimeSourceForTesting(
1045 make_scoped_ptr(new TestTimeSource(clock_)));
1046 scheduler_->GetSchedulerHelperForTesting()
1047 ->GetTaskQueueManagerForTesting()
1048 ->SetTimeSourceForTesting(make_scoped_ptr(new TestTimeSource(clock_)));
1049 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
1051 scheduler_->DidReceiveInputEventOnCompositorThread(
1052 FakeInputEvent(blink::WebInputEvent::TouchStart));
1053 scheduler_->DidReceiveInputEventOnCompositorThread(
1054 FakeInputEvent(blink::WebInputEvent::TouchMove));
1056 // We expect the first call to IsHighPriorityWorkAnticipated to be called
1057 // after recieving an input event (but before the UpdateTask was processed) to
1058 // call UpdatePolicy.
1059 EXPECT_EQ(0, mock_scheduler->update_policy_count_);
1060 scheduler_->IsHighPriorityWorkAnticipated();
1061 EXPECT_EQ(1, mock_scheduler->update_policy_count_);
1062 // Subsequent calls should not call UpdatePolicy.
1063 scheduler_->IsHighPriorityWorkAnticipated();
1064 scheduler_->IsHighPriorityWorkAnticipated();
1065 scheduler_->IsHighPriorityWorkAnticipated();
1066 scheduler_->ShouldYieldForHighPriorityWork();
1067 scheduler_->ShouldYieldForHighPriorityWork();
1068 scheduler_->ShouldYieldForHighPriorityWork();
1069 scheduler_->ShouldYieldForHighPriorityWork();
1071 EXPECT_EQ(1, mock_scheduler->update_policy_count_);
1073 RunUntilIdle();
1074 // We expect both the urgent and the delayed updates to run in addition to the
1075 // earlier updated cause by IsHighPriorityWorkAnticipated.
1076 EXPECT_EQ(3, mock_scheduler->update_policy_count_);
1079 class RendererSchedulerImplWithMessageLoopTest
1080 : public RendererSchedulerImplTest {
1081 public:
1082 RendererSchedulerImplWithMessageLoopTest()
1083 : RendererSchedulerImplTest(new base::MessageLoop()) {}
1084 ~RendererSchedulerImplWithMessageLoopTest() override {}
1086 void PostFromNestedRunloop(std::vector<
1087 std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>>* tasks) {
1088 base::MessageLoop::ScopedNestableTaskAllower allow(message_loop_.get());
1089 for (std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>& pair : *tasks) {
1090 if (pair.second) {
1091 idle_task_runner_->PostIdleTask(FROM_HERE, pair.first);
1092 } else {
1093 idle_task_runner_->PostNonNestableIdleTask(FROM_HERE, pair.first);
1096 EnableIdleTasks();
1097 message_loop_->RunUntilIdle();
1100 private:
1101 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImplWithMessageLoopTest);
1104 TEST_F(RendererSchedulerImplWithMessageLoopTest,
1105 NonNestableIdleTaskDoesntExecuteInNestedLoop) {
1106 std::vector<std::string> order;
1107 idle_task_runner_->PostIdleTask(
1108 FROM_HERE,
1109 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("1")));
1110 idle_task_runner_->PostIdleTask(
1111 FROM_HERE,
1112 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("2")));
1114 std::vector<std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>>
1115 tasks_to_post_from_nested_loop;
1116 tasks_to_post_from_nested_loop.push_back(std::make_pair(
1117 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("3")),
1118 false));
1119 tasks_to_post_from_nested_loop.push_back(std::make_pair(
1120 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("4")), true));
1121 tasks_to_post_from_nested_loop.push_back(std::make_pair(
1122 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("5")), true));
1124 default_task_runner_->PostTask(
1125 FROM_HERE,
1126 base::Bind(
1127 &RendererSchedulerImplWithMessageLoopTest::PostFromNestedRunloop,
1128 base::Unretained(this),
1129 base::Unretained(&tasks_to_post_from_nested_loop)));
1131 EnableIdleTasks();
1132 RunUntilIdle();
1133 // Note we expect task 3 to run last because it's non-nestable.
1134 EXPECT_THAT(order, testing::ElementsAre(std::string("1"), std::string("2"),
1135 std::string("4"), std::string("5"),
1136 std::string("3")));
1139 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriod) {
1140 base::TimeTicks expected_deadline =
1141 clock_->Now() + maximum_idle_period_duration();
1142 base::TimeTicks deadline_in_task;
1143 int run_count = 0;
1145 idle_task_runner_->PostIdleTask(
1146 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
1148 RunUntilIdle();
1149 EXPECT_EQ(0, run_count); // Shouldn't run yet as no idle period.
1151 scheduler_->BeginFrameNotExpectedSoon();
1152 RunUntilIdle();
1153 EXPECT_EQ(1, run_count); // Should have run in a long idle time.
1154 EXPECT_EQ(expected_deadline, deadline_in_task);
1157 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodWithPendingDelayedTask) {
1158 base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(30);
1159 base::TimeTicks expected_deadline = clock_->Now() + pending_task_delay;
1160 base::TimeTicks deadline_in_task;
1161 int run_count = 0;
1163 idle_task_runner_->PostIdleTask(
1164 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
1165 default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask),
1166 pending_task_delay);
1168 scheduler_->BeginFrameNotExpectedSoon();
1169 RunUntilIdle();
1170 EXPECT_EQ(1, run_count); // Should have run in a long idle time.
1171 EXPECT_EQ(expected_deadline, deadline_in_task);
1174 TEST_F(RendererSchedulerImplTest,
1175 TestLongIdlePeriodWithLatePendingDelayedTask) {
1176 base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(10);
1177 base::TimeTicks deadline_in_task;
1178 int run_count = 0;
1180 default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask),
1181 pending_task_delay);
1183 // Advance clock until after delayed task was meant to be run.
1184 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(20));
1186 // Post an idle task and BeginFrameNotExpectedSoon to initiate a long idle
1187 // period. Since there is a late pending delayed task this shouldn't actually
1188 // start an idle period.
1189 idle_task_runner_->PostIdleTask(
1190 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
1191 scheduler_->BeginFrameNotExpectedSoon();
1192 RunUntilIdle();
1193 EXPECT_EQ(0, run_count);
1195 // After the delayed task has been run we should trigger an idle period.
1196 clock_->AdvanceNow(maximum_idle_period_duration());
1197 RunUntilIdle();
1198 EXPECT_EQ(1, run_count);
1201 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodRepeating) {
1202 int run_count = 0;
1204 max_idle_task_reposts = 3;
1205 idle_task_runner_->PostIdleTask(
1206 FROM_HERE,
1207 base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
1209 scheduler_->BeginFrameNotExpectedSoon();
1210 RunUntilIdle();
1211 EXPECT_EQ(1, run_count); // Should only run once per idle period.
1213 // Advance time to start of next long idle period and check task reposted task
1214 // gets run.
1215 clock_->AdvanceNow(maximum_idle_period_duration());
1216 RunUntilIdle();
1217 EXPECT_EQ(2, run_count);
1219 // Advance time to start of next long idle period then end idle period with a
1220 // new BeginMainFrame and check idle task doesn't run.
1221 clock_->AdvanceNow(maximum_idle_period_duration());
1222 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
1223 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
1224 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
1225 RunUntilIdle();
1226 EXPECT_EQ(2, run_count);
1229 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodDoesNotWakeScheduler) {
1230 base::TimeTicks deadline_in_task;
1231 int run_count = 0;
1233 // Start a long idle period and get the time it should end.
1234 scheduler_->BeginFrameNotExpectedSoon();
1235 // The scheduler should not run the initiate_next_long_idle_period task if
1236 // there are no idle tasks and no other task woke up the scheduler, thus
1237 // the idle period deadline shouldn't update at the end of the current long
1238 // idle period.
1239 base::TimeTicks idle_period_deadline =
1240 scheduler_->CurrentIdleTaskDeadlineForTesting();
1241 clock_->AdvanceNow(maximum_idle_period_duration());
1242 RunUntilIdle();
1244 base::TimeTicks new_idle_period_deadline =
1245 scheduler_->CurrentIdleTaskDeadlineForTesting();
1246 EXPECT_EQ(idle_period_deadline, new_idle_period_deadline);
1248 // Posting a after-wakeup idle task also shouldn't wake the scheduler or
1249 // initiate the next long idle period.
1250 idle_task_runner_->PostIdleTaskAfterWakeup(
1251 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
1252 RunUntilIdle();
1253 new_idle_period_deadline = scheduler_->CurrentIdleTaskDeadlineForTesting();
1254 EXPECT_EQ(idle_period_deadline, new_idle_period_deadline);
1255 EXPECT_EQ(0, run_count);
1257 // Running a normal task should initiate a new long idle period though.
1258 default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
1259 RunUntilIdle();
1260 new_idle_period_deadline = scheduler_->CurrentIdleTaskDeadlineForTesting();
1261 EXPECT_EQ(idle_period_deadline + maximum_idle_period_duration(),
1262 new_idle_period_deadline);
1264 EXPECT_EQ(1, run_count);
1267 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodInTouchStartPolicy) {
1268 base::TimeTicks deadline_in_task;
1269 int run_count = 0;
1271 idle_task_runner_->PostIdleTask(
1272 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
1274 // Observation of touchstart should defer the start of the long idle period.
1275 scheduler_->DidReceiveInputEventOnCompositorThread(
1276 FakeInputEvent(blink::WebInputEvent::TouchStart));
1277 scheduler_->BeginFrameNotExpectedSoon();
1278 RunUntilIdle();
1279 EXPECT_EQ(0, run_count);
1281 // The long idle period should start after the touchstart policy has finished.
1282 clock_->AdvanceNow(priority_escalation_after_input_duration());
1283 RunUntilIdle();
1284 EXPECT_EQ(1, run_count);
1287 void TestCanExceedIdleDeadlineIfRequiredTask(RendererScheduler* scheduler,
1288 bool* can_exceed_idle_deadline_out,
1289 int* run_count,
1290 base::TimeTicks deadline) {
1291 *can_exceed_idle_deadline_out = scheduler->CanExceedIdleDeadlineIfRequired();
1292 (*run_count)++;
1295 TEST_F(RendererSchedulerImplTest, CanExceedIdleDeadlineIfRequired) {
1296 int run_count = 0;
1297 bool can_exceed_idle_deadline = false;
1299 // Should return false if not in an idle period.
1300 EXPECT_FALSE(scheduler_->CanExceedIdleDeadlineIfRequired());
1302 // Should return false for short idle periods.
1303 idle_task_runner_->PostIdleTask(
1304 FROM_HERE,
1305 base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(),
1306 &can_exceed_idle_deadline, &run_count));
1307 EnableIdleTasks();
1308 RunUntilIdle();
1309 EXPECT_EQ(1, run_count);
1310 EXPECT_FALSE(can_exceed_idle_deadline);
1312 // Should return false for a long idle period which is shortened due to a
1313 // pending delayed task.
1314 default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask),
1315 base::TimeDelta::FromMilliseconds(10));
1316 idle_task_runner_->PostIdleTask(
1317 FROM_HERE,
1318 base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(),
1319 &can_exceed_idle_deadline, &run_count));
1320 scheduler_->BeginFrameNotExpectedSoon();
1321 RunUntilIdle();
1322 EXPECT_EQ(2, run_count);
1323 EXPECT_FALSE(can_exceed_idle_deadline);
1325 // Next long idle period will be for the maximum time, so
1326 // CanExceedIdleDeadlineIfRequired should return true.
1327 clock_->AdvanceNow(maximum_idle_period_duration());
1328 idle_task_runner_->PostIdleTask(
1329 FROM_HERE,
1330 base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(),
1331 &can_exceed_idle_deadline, &run_count));
1332 RunUntilIdle();
1333 EXPECT_EQ(3, run_count);
1334 EXPECT_TRUE(can_exceed_idle_deadline);
1336 // Next long idle period will be for the maximum time, so
1337 // CanExceedIdleDeadlineIfRequired should return true.
1338 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
1339 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
1340 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
1341 EXPECT_FALSE(scheduler_->CanExceedIdleDeadlineIfRequired());
1344 TEST_F(RendererSchedulerImplTest, TestRendererHiddenIdlePeriod) {
1345 int run_count = 0;
1347 idle_task_runner_->PostIdleTask(
1348 FROM_HERE,
1349 base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
1351 // Renderer should start in visible state.
1352 RunUntilIdle();
1353 EXPECT_EQ(0, run_count);
1355 // When we hide the renderer it should start an idle period.
1356 scheduler_->OnRendererHidden();
1357 RunUntilIdle();
1358 EXPECT_EQ(1, run_count);
1360 // Advance time to start of next long idle period and check task reposted task
1361 // gets run.
1362 clock_->AdvanceNow(maximum_idle_period_duration());
1363 RunUntilIdle();
1364 EXPECT_EQ(2, run_count);
1366 // Advance time by amount of time by the maximum amount of time we execute
1367 // idle tasks when hidden (plus some slack) - idle period should have ended.
1368 clock_->AdvanceNow(end_idle_when_hidden_delay() +
1369 base::TimeDelta::FromMilliseconds(10));
1370 RunUntilIdle();
1371 EXPECT_EQ(2, run_count);
1374 TEST_F(RendererSchedulerImplTest, TimerQueueEnabledByDefault) {
1375 std::vector<std::string> run_order;
1376 PostTestTasks(&run_order, "T1 T2");
1377 RunUntilIdle();
1378 EXPECT_THAT(run_order,
1379 testing::ElementsAre(std::string("T1"), std::string("T2")));
1382 TEST_F(RendererSchedulerImplTest, SuspendAndResumeTimerQueue) {
1383 std::vector<std::string> run_order;
1384 PostTestTasks(&run_order, "T1 T2");
1386 scheduler_->SuspendTimerQueue();
1387 RunUntilIdle();
1388 EXPECT_TRUE(run_order.empty());
1390 scheduler_->ResumeTimerQueue();
1391 RunUntilIdle();
1392 EXPECT_THAT(run_order,
1393 testing::ElementsAre(std::string("T1"), std::string("T2")));
1396 TEST_F(RendererSchedulerImplTest, MultipleSuspendsNeedMultipleResumes) {
1397 std::vector<std::string> run_order;
1398 PostTestTasks(&run_order, "T1 T2");
1400 scheduler_->SuspendTimerQueue();
1401 scheduler_->SuspendTimerQueue();
1402 scheduler_->SuspendTimerQueue();
1403 RunUntilIdle();
1404 EXPECT_TRUE(run_order.empty());
1406 scheduler_->ResumeTimerQueue();
1407 RunUntilIdle();
1408 EXPECT_TRUE(run_order.empty());
1410 scheduler_->ResumeTimerQueue();
1411 RunUntilIdle();
1412 EXPECT_TRUE(run_order.empty());
1414 scheduler_->ResumeTimerQueue();
1415 RunUntilIdle();
1416 EXPECT_THAT(run_order,
1417 testing::ElementsAre(std::string("T1"), std::string("T2")));
1420 } // namespace scheduler