Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: content/renderer/scheduler/renderer_scheduler_impl_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698