| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "content/renderer/scheduler/renderer_scheduler_impl.h" | |
| 6 | |
| 7 #include "base/callback.h" | |
| 8 #include "cc/output/begin_frame_args.h" | |
| 9 #include "cc/test/ordered_simple_task_runner.h" | |
| 10 #include "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 | |
| OLD | NEW |