OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "components/scheduler/renderer/renderer_scheduler_impl.h" | 5 #include "components/scheduler/renderer/renderer_scheduler_impl.h" |
6 | 6 |
7 #include "base/callback.h" | 7 #include "base/callback.h" |
8 #include "cc/output/begin_frame_args.h" | 8 #include "cc/output/begin_frame_args.h" |
9 #include "cc/test/ordered_simple_task_runner.h" | 9 #include "cc/test/ordered_simple_task_runner.h" |
10 #include "cc/test/test_now_source.h" | 10 #include "cc/test/test_now_source.h" |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
71 int* run_count, | 71 int* run_count, |
72 base::TimeTicks deadline) { | 72 base::TimeTicks deadline) { |
73 if ((*run_count + 1) < max_idle_task_reposts) { | 73 if ((*run_count + 1) < max_idle_task_reposts) { |
74 idle_task_runner->PostIdleTask( | 74 idle_task_runner->PostIdleTask( |
75 FROM_HERE, base::Bind(&RepostingIdleTestTask, | 75 FROM_HERE, base::Bind(&RepostingIdleTestTask, |
76 base::Unretained(idle_task_runner), run_count)); | 76 base::Unretained(idle_task_runner), run_count)); |
77 } | 77 } |
78 (*run_count)++; | 78 (*run_count)++; |
79 } | 79 } |
80 | 80 |
| 81 void RepostingUpdateClockIdleTestTask( |
| 82 SingleThreadIdleTaskRunner* idle_task_runner, |
| 83 int* run_count, |
| 84 scoped_refptr<cc::TestNowSource> clock, |
| 85 base::TimeDelta advance_time, |
| 86 std::vector<base::TimeTicks>* deadlines, |
| 87 base::TimeTicks deadline) { |
| 88 if ((*run_count + 1) < max_idle_task_reposts) { |
| 89 idle_task_runner->PostIdleTask( |
| 90 FROM_HERE, base::Bind(&RepostingUpdateClockIdleTestTask, |
| 91 base::Unretained(idle_task_runner), run_count, |
| 92 clock, advance_time, deadlines)); |
| 93 } |
| 94 deadlines->push_back(deadline); |
| 95 (*run_count)++; |
| 96 clock->AdvanceNow(advance_time); |
| 97 } |
| 98 |
| 99 void WillBeginFrameIdleTask(RendererScheduler* scheduler, |
| 100 scoped_refptr<cc::TestNowSource> clock, |
| 101 base::TimeTicks deadline) { |
| 102 scheduler->WillBeginFrame(cc::BeginFrameArgs::Create( |
| 103 BEGINFRAME_FROM_HERE, clock->Now(), base::TimeTicks(), |
| 104 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL)); |
| 105 } |
| 106 |
81 void UpdateClockToDeadlineIdleTestTask( | 107 void UpdateClockToDeadlineIdleTestTask( |
82 cc::TestNowSource* clock, | 108 cc::TestNowSource* clock, |
83 base::SingleThreadTaskRunner* task_runner, | |
84 int* run_count, | 109 int* run_count, |
85 base::TimeTicks deadline) { | 110 base::TimeTicks deadline) { |
86 clock->SetNow(deadline); | 111 clock->SetNow(deadline); |
87 // Due to the way in which OrderedSimpleTestRunner orders tasks and the fact | |
88 // that we updated the time within a task, the delayed pending task to call | |
89 // EndIdlePeriod will not happen until after a TaskQueueManager DoWork, so | |
90 // post a normal task here to ensure it runs before the next idle task. | |
91 task_runner->PostTask(FROM_HERE, base::Bind(NullTask)); | |
92 (*run_count)++; | 112 (*run_count)++; |
93 } | 113 } |
94 | 114 |
95 void PostingYieldingTestTask(RendererSchedulerImpl* scheduler, | 115 void PostingYieldingTestTask(RendererSchedulerImpl* scheduler, |
96 base::SingleThreadTaskRunner* task_runner, | 116 base::SingleThreadTaskRunner* task_runner, |
97 bool simulate_input, | 117 bool simulate_input, |
98 bool* should_yield_before, | 118 bool* should_yield_before, |
99 bool* should_yield_after) { | 119 bool* should_yield_after) { |
100 *should_yield_before = scheduler->ShouldYieldForHighPriorityWork(); | 120 *should_yield_before = scheduler->ShouldYieldForHighPriorityWork(); |
101 task_runner->PostTask(FROM_HERE, base::Bind(NullTask)); | 121 task_runner->PostTask(FROM_HERE, base::Bind(NullTask)); |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 RunUntilIdle(); | 399 RunUntilIdle(); |
380 EXPECT_EQ(2, run_count); | 400 EXPECT_EQ(2, run_count); |
381 } | 401 } |
382 | 402 |
383 TEST_F(RendererSchedulerImplTest, TestIdleTaskExceedsDeadline) { | 403 TEST_F(RendererSchedulerImplTest, TestIdleTaskExceedsDeadline) { |
384 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true); | 404 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true); |
385 int run_count = 0; | 405 int run_count = 0; |
386 | 406 |
387 // Post two UpdateClockToDeadlineIdleTestTask tasks. | 407 // Post two UpdateClockToDeadlineIdleTestTask tasks. |
388 idle_task_runner_->PostIdleTask( | 408 idle_task_runner_->PostIdleTask( |
389 FROM_HERE, base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_, | 409 FROM_HERE, |
390 default_task_runner_, &run_count)); | 410 base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_, &run_count)); |
391 idle_task_runner_->PostIdleTask( | 411 idle_task_runner_->PostIdleTask( |
392 FROM_HERE, base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_, | 412 FROM_HERE, |
393 default_task_runner_, &run_count)); | 413 base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_, &run_count)); |
394 | 414 |
395 EnableIdleTasks(); | 415 EnableIdleTasks(); |
396 RunUntilIdle(); | 416 RunUntilIdle(); |
397 // Only the first idle task should execute since it's used up the deadline. | 417 // Only the first idle task should execute since it's used up the deadline. |
398 EXPECT_EQ(1, run_count); | 418 EXPECT_EQ(1, run_count); |
399 | 419 |
400 EnableIdleTasks(); | 420 EnableIdleTasks(); |
401 RunUntilIdle(); | 421 RunUntilIdle(); |
402 // Second task should be run on the next idle period. | 422 // Second task should be run on the next idle period. |
403 EXPECT_EQ(2, run_count); | 423 EXPECT_EQ(2, run_count); |
(...skipping 799 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1203 RunUntilIdle(); | 1223 RunUntilIdle(); |
1204 EXPECT_EQ(0, run_count); | 1224 EXPECT_EQ(0, run_count); |
1205 | 1225 |
1206 // After the delayed task has been run we should trigger an idle period. | 1226 // After the delayed task has been run we should trigger an idle period. |
1207 clock_->AdvanceNow(maximum_idle_period_duration()); | 1227 clock_->AdvanceNow(maximum_idle_period_duration()); |
1208 RunUntilIdle(); | 1228 RunUntilIdle(); |
1209 EXPECT_EQ(1, run_count); | 1229 EXPECT_EQ(1, run_count); |
1210 } | 1230 } |
1211 | 1231 |
1212 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodRepeating) { | 1232 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodRepeating) { |
| 1233 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true); |
| 1234 std::vector<base::TimeTicks> actual_deadlines; |
1213 int run_count = 0; | 1235 int run_count = 0; |
1214 | 1236 |
1215 max_idle_task_reposts = 3; | 1237 max_idle_task_reposts = 3; |
| 1238 base::TimeTicks clock_before(clock_->Now()); |
| 1239 base::TimeDelta idle_task_runtime(base::TimeDelta::FromMilliseconds(10)); |
1216 idle_task_runner_->PostIdleTask( | 1240 idle_task_runner_->PostIdleTask( |
1217 FROM_HERE, | 1241 FROM_HERE, |
1218 base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count)); | 1242 base::Bind(&RepostingUpdateClockIdleTestTask, idle_task_runner_, |
1219 | 1243 &run_count, clock_, idle_task_runtime, &actual_deadlines)); |
1220 scheduler_->BeginFrameNotExpectedSoon(); | 1244 scheduler_->BeginFrameNotExpectedSoon(); |
1221 RunUntilIdle(); | 1245 RunUntilIdle(); |
1222 EXPECT_EQ(1, run_count); // Should only run once per idle period. | 1246 EXPECT_EQ(3, run_count); |
| 1247 EXPECT_THAT( |
| 1248 actual_deadlines, |
| 1249 testing::ElementsAre( |
| 1250 clock_before + maximum_idle_period_duration(), |
| 1251 clock_before + idle_task_runtime + maximum_idle_period_duration(), |
| 1252 clock_before + (2 * idle_task_runtime) + |
| 1253 maximum_idle_period_duration())); |
1223 | 1254 |
1224 // Advance time to start of next long idle period and check task reposted task | 1255 // Check that idle tasks don't run after the idle period ends with a |
1225 // gets run. | 1256 // new BeginMainFrame. |
1226 clock_->AdvanceNow(maximum_idle_period_duration()); | 1257 max_idle_task_reposts = 5; |
| 1258 idle_task_runner_->PostIdleTask( |
| 1259 FROM_HERE, |
| 1260 base::Bind(&RepostingUpdateClockIdleTestTask, idle_task_runner_, |
| 1261 &run_count, clock_, idle_task_runtime, &actual_deadlines)); |
| 1262 idle_task_runner_->PostIdleTask( |
| 1263 FROM_HERE, base::Bind(&WillBeginFrameIdleTask, |
| 1264 base::Unretained(scheduler_.get()), clock_)); |
1227 RunUntilIdle(); | 1265 RunUntilIdle(); |
1228 EXPECT_EQ(2, run_count); | 1266 EXPECT_EQ(4, run_count); |
1229 | |
1230 // Advance time to start of next long idle period then end idle period with a | |
1231 // new BeginMainFrame and check idle task doesn't run. | |
1232 clock_->AdvanceNow(maximum_idle_period_duration()); | |
1233 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create( | |
1234 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(), | |
1235 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL)); | |
1236 RunUntilIdle(); | |
1237 EXPECT_EQ(2, run_count); | |
1238 } | 1267 } |
1239 | 1268 |
1240 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodDoesNotWakeScheduler) { | 1269 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodDoesNotWakeScheduler) { |
1241 base::TimeTicks deadline_in_task; | 1270 base::TimeTicks deadline_in_task; |
1242 int run_count = 0; | 1271 int run_count = 0; |
1243 | 1272 |
1244 // Start a long idle period and get the time it should end. | 1273 // Start a long idle period and get the time it should end. |
1245 scheduler_->BeginFrameNotExpectedSoon(); | 1274 scheduler_->BeginFrameNotExpectedSoon(); |
1246 // The scheduler should not run the initiate_next_long_idle_period task if | 1275 // The scheduler should not run the initiate_next_long_idle_period task if |
1247 // there are no idle tasks and no other task woke up the scheduler, thus | 1276 // there are no idle tasks and no other task woke up the scheduler, thus |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1348 // CanExceedIdleDeadlineIfRequired should return true. | 1377 // CanExceedIdleDeadlineIfRequired should return true. |
1349 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create( | 1378 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create( |
1350 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(), | 1379 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(), |
1351 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL)); | 1380 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL)); |
1352 EXPECT_FALSE(scheduler_->CanExceedIdleDeadlineIfRequired()); | 1381 EXPECT_FALSE(scheduler_->CanExceedIdleDeadlineIfRequired()); |
1353 } | 1382 } |
1354 | 1383 |
1355 TEST_F(RendererSchedulerImplTest, TestRendererHiddenIdlePeriod) { | 1384 TEST_F(RendererSchedulerImplTest, TestRendererHiddenIdlePeriod) { |
1356 int run_count = 0; | 1385 int run_count = 0; |
1357 | 1386 |
| 1387 max_idle_task_reposts = 2; |
1358 idle_task_runner_->PostIdleTask( | 1388 idle_task_runner_->PostIdleTask( |
1359 FROM_HERE, | 1389 FROM_HERE, |
1360 base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count)); | 1390 base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count)); |
1361 | 1391 |
1362 // Renderer should start in visible state. | 1392 // Renderer should start in visible state. |
1363 RunUntilIdle(); | 1393 RunUntilIdle(); |
1364 EXPECT_EQ(0, run_count); | 1394 EXPECT_EQ(0, run_count); |
1365 | 1395 |
1366 // When we hide the renderer it should start an idle period. | 1396 // When we hide the renderer it should start a max deadline idle period, which |
| 1397 // will run an idle task and then immediately start a new idle period, which |
| 1398 // runs the second idle task. |
1367 scheduler_->OnRendererHidden(); | 1399 scheduler_->OnRendererHidden(); |
1368 RunUntilIdle(); | 1400 RunUntilIdle(); |
1369 EXPECT_EQ(1, run_count); | |
1370 | |
1371 // Advance time to start of next long idle period and check task reposted task | |
1372 // gets run. | |
1373 clock_->AdvanceNow(maximum_idle_period_duration()); | |
1374 RunUntilIdle(); | |
1375 EXPECT_EQ(2, run_count); | 1401 EXPECT_EQ(2, run_count); |
1376 | 1402 |
1377 // Advance time by amount of time by the maximum amount of time we execute | 1403 // Advance time by amount of time by the maximum amount of time we execute |
1378 // idle tasks when hidden (plus some slack) - idle period should have ended. | 1404 // idle tasks when hidden (plus some slack) - idle period should have ended. |
| 1405 max_idle_task_reposts = 3; |
| 1406 idle_task_runner_->PostIdleTask( |
| 1407 FROM_HERE, |
| 1408 base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count)); |
1379 clock_->AdvanceNow(end_idle_when_hidden_delay() + | 1409 clock_->AdvanceNow(end_idle_when_hidden_delay() + |
1380 base::TimeDelta::FromMilliseconds(10)); | 1410 base::TimeDelta::FromMilliseconds(10)); |
1381 RunUntilIdle(); | 1411 RunUntilIdle(); |
1382 EXPECT_EQ(2, run_count); | 1412 EXPECT_EQ(2, run_count); |
1383 } | 1413 } |
1384 | 1414 |
1385 TEST_F(RendererSchedulerImplTest, TimerQueueEnabledByDefault) { | 1415 TEST_F(RendererSchedulerImplTest, TimerQueueEnabledByDefault) { |
1386 std::vector<std::string> run_order; | 1416 std::vector<std::string> run_order; |
1387 PostTestTasks(&run_order, "T1 T2"); | 1417 PostTestTasks(&run_order, "T1 T2"); |
1388 RunUntilIdle(); | 1418 RunUntilIdle(); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1434 | 1464 |
1435 TEST_F(RendererSchedulerImplTest, PolicyToString) { | 1465 TEST_F(RendererSchedulerImplTest, PolicyToString) { |
1436 CheckAllTaskQueueIdToString(); | 1466 CheckAllTaskQueueIdToString(); |
1437 } | 1467 } |
1438 | 1468 |
1439 TEST_F(RendererSchedulerImplTest, InputStreamStateToString) { | 1469 TEST_F(RendererSchedulerImplTest, InputStreamStateToString) { |
1440 CheckAllInputStreamStateToString(); | 1470 CheckAllInputStreamStateToString(); |
1441 } | 1471 } |
1442 | 1472 |
1443 } // namespace scheduler | 1473 } // namespace scheduler |
OLD | NEW |