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