Chromium Code Reviews| 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 scoped_refptr<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, task_runner, vector, | |
| 44 reentrant_count, max_reentrant_count)); | |
| 45 } | |
| 46 } | |
| 47 | |
| 48 void IdleTestTask(int* run_count, | |
| 49 base::TimeTicks* deadline_out, | |
| 50 base::TimeTicks deadline) { | |
| 51 (*run_count)++; | |
| 52 *deadline_out = deadline; | |
| 53 } | |
| 54 | |
| 55 int max_idle_task_reposts = 2; | |
| 56 | |
| 57 void RepostingIdleTestTask( | |
| 58 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner, | |
| 59 int* run_count, | |
| 60 base::TimeTicks deadline) { | |
| 61 if ((*run_count + 1) < max_idle_task_reposts) { | |
| 62 idle_task_runner->PostIdleTask( | |
| 63 FROM_HERE, | |
| 64 base::Bind(&RepostingIdleTestTask, idle_task_runner, run_count)); | |
| 65 } | |
| 66 (*run_count)++; | |
| 67 } | |
| 68 | |
| 43 }; // namespace | 69 }; // namespace |
| 44 | 70 |
| 45 class RendererSchedulerImplTest : public testing::Test { | 71 class SchedulerHelperForTest : public SchedulerHelper, |
| 72 public SchedulerHelper::SchedulerHelperDelegate { | |
| 46 public: | 73 public: |
| 47 using Policy = RendererSchedulerImpl::Policy; | 74 explicit SchedulerHelperForTest( |
| 75 scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner) | |
| 76 : SchedulerHelper(main_task_runner, | |
| 77 this, | |
| 78 "test.scheduler", | |
| 79 TRACE_DISABLED_BY_DEFAULT("test.scheduler"), | |
| 80 TASK_QUEUE_COUNT) {} | |
| 48 | 81 |
| 49 RendererSchedulerImplTest() | 82 ~SchedulerHelperForTest() override {} |
| 83 | |
| 84 using IdlePeriodState = SchedulerHelper::IdlePeriodState; | |
| 85 using SchedulerHelper::CanExceedIdleDeadlineIfRequired; | |
| 86 using SchedulerHelper::EndIdlePeriod; | |
| 87 using SchedulerHelper::StartIdlePeriod; | |
| 88 using SchedulerHelper::InitiateLongIdlePeriod; | |
| 89 using SchedulerHelper::EstimatedEndOfIdle; | |
| 90 | |
| 91 // SchedulerHelperDelegate implementation: | |
| 92 MOCK_METHOD2(CanEnterLongIdlePeriod, | |
| 93 bool(base::TimeTicks now, | |
| 94 base::TimeDelta* next_long_idle_period_delay_out)); | |
| 95 }; | |
| 96 | |
| 97 class SchedulerHelperTest : public testing::Test { | |
| 98 public: | |
| 99 SchedulerHelperTest() | |
| 50 : clock_(cc::TestNowSource::Create(5000)), | 100 : clock_(cc::TestNowSource::Create(5000)), |
| 51 mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_, false)), | 101 mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_, false)), |
| 52 nestable_task_runner_( | 102 nestable_task_runner_( |
| 53 NestableTaskRunnerForTest::Create(mock_task_runner_)), | 103 NestableTaskRunnerForTest::Create(mock_task_runner_)), |
| 54 scheduler_(new RendererSchedulerImpl(nestable_task_runner_)), | 104 scheduler_helper_(new SchedulerHelperForTest(nestable_task_runner_)), |
| 55 default_task_runner_(scheduler_->DefaultTaskRunner()), | 105 default_task_runner_(scheduler_helper_->DefaultTaskRunner()), |
| 56 compositor_task_runner_(scheduler_->CompositorTaskRunner()), | 106 idle_task_runner_(scheduler_helper_->IdleTaskRunner()) { |
| 57 loading_task_runner_(scheduler_->LoadingTaskRunner()), | 107 scheduler_helper_->SetTimeSourceForTesting(clock_); |
| 58 idle_task_runner_(scheduler_->IdleTaskRunner()) { | |
| 59 scheduler_->SetTimeSourceForTesting(clock_); | |
| 60 } | 108 } |
| 61 | 109 |
| 62 RendererSchedulerImplTest(base::MessageLoop* message_loop) | 110 SchedulerHelperTest(base::MessageLoop* message_loop) |
| 63 : clock_(cc::TestNowSource::Create(5000)), | 111 : clock_(cc::TestNowSource::Create(5000)), |
| 64 message_loop_(message_loop), | 112 message_loop_(message_loop), |
| 65 nestable_task_runner_( | 113 nestable_task_runner_( |
| 66 RendererSchedulerMessageLoopDelegate::Create(message_loop)), | 114 SchedulerMessageLoopDelegate::Create(message_loop)), |
| 67 scheduler_(new RendererSchedulerImpl(nestable_task_runner_)), | 115 scheduler_helper_(new SchedulerHelperForTest(nestable_task_runner_)), |
| 68 default_task_runner_(scheduler_->DefaultTaskRunner()), | 116 default_task_runner_(scheduler_helper_->DefaultTaskRunner()), |
| 69 compositor_task_runner_(scheduler_->CompositorTaskRunner()), | 117 idle_task_runner_(scheduler_helper_->IdleTaskRunner()) { |
| 70 loading_task_runner_(scheduler_->LoadingTaskRunner()), | 118 scheduler_helper_->SetTimeSourceForTesting(clock_); |
| 71 idle_task_runner_(scheduler_->IdleTaskRunner()) { | |
| 72 scheduler_->SetTimeSourceForTesting(clock_); | |
| 73 } | 119 } |
| 74 ~RendererSchedulerImplTest() override {} | 120 ~SchedulerHelperTest() override {} |
| 75 | 121 |
| 76 void TearDown() override { | 122 void TearDown() override { |
| 77 DCHECK(!mock_task_runner_.get() || !message_loop_.get()); | 123 DCHECK(!mock_task_runner_.get() || !message_loop_.get()); |
| 78 if (mock_task_runner_.get()) { | 124 if (mock_task_runner_.get()) { |
| 79 // Check that all tests stop posting tasks. | 125 // Check that all tests stop posting tasks. |
| 80 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true); | 126 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true); |
| 81 while (mock_task_runner_->RunUntilIdle()) { | 127 while (mock_task_runner_->RunUntilIdle()) { |
| 82 } | 128 } |
| 83 } else { | 129 } else { |
| 84 message_loop_->RunUntilIdle(); | 130 message_loop_->RunUntilIdle(); |
| 85 } | 131 } |
| 86 } | 132 } |
| 87 | 133 |
| 88 void RunUntilIdle() { | 134 void RunUntilIdle() { |
| 89 // Only one of mock_task_runner_ or message_loop_ should be set. | 135 // Only one of mock_task_runner_ or message_loop_ should be set. |
| 90 DCHECK(!mock_task_runner_.get() || !message_loop_.get()); | 136 DCHECK(!mock_task_runner_.get() || !message_loop_.get()); |
| 91 if (mock_task_runner_.get()) | 137 if (mock_task_runner_.get()) |
| 92 mock_task_runner_->RunUntilIdle(); | 138 mock_task_runner_->RunUntilIdle(); |
| 93 else | 139 else |
| 94 message_loop_->RunUntilIdle(); | 140 message_loop_->RunUntilIdle(); |
| 95 } | 141 } |
| 96 | 142 |
| 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 | 143 // Helper for posting several tasks of specific types. |task_descriptor| is a |
| 119 // string with space delimited task identifiers. The first letter of each | 144 // string with space delimited task identifiers. The first letter of each |
| 120 // task identifier specifies the task type: | 145 // task identifier specifies the task type: |
| 121 // - 'D': Default task | 146 // - 'D': Default task |
| 122 // - 'C': Compositor task | |
| 123 // - 'L': Loading task | |
| 124 // - 'I': Idle task | 147 // - 'I': Idle task |
| 125 void PostTestTasks(std::vector<std::string>* run_order, | 148 void PostTestTasks(std::vector<std::string>* run_order, |
| 126 const std::string& task_descriptor) { | 149 const std::string& task_descriptor) { |
| 127 std::istringstream stream(task_descriptor); | 150 std::istringstream stream(task_descriptor); |
| 128 while (!stream.eof()) { | 151 while (!stream.eof()) { |
| 129 std::string task; | 152 std::string task; |
| 130 stream >> task; | 153 stream >> task; |
| 131 switch (task[0]) { | 154 switch (task[0]) { |
| 132 case 'D': | 155 case 'D': |
| 133 default_task_runner_->PostTask( | 156 default_task_runner_->PostTask( |
| 134 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task)); | 157 FROM_HERE, base::Bind(&AppendToVectorTestTask, run_order, task)); |
| 135 break; | 158 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': | 159 case 'I': |
| 145 idle_task_runner_->PostIdleTask( | 160 idle_task_runner_->PostIdleTask( |
| 146 FROM_HERE, | 161 FROM_HERE, |
| 147 base::Bind(&AppendToVectorIdleTestTask, run_order, task)); | 162 base::Bind(&AppendToVectorIdleTestTask, run_order, task)); |
| 148 break; | 163 break; |
| 149 default: | 164 default: |
| 150 NOTREACHED(); | 165 NOTREACHED(); |
| 151 } | 166 } |
| 152 } | 167 } |
| 153 } | 168 } |
| 154 | 169 |
| 155 protected: | 170 protected: |
| 156 static base::TimeDelta priority_escalation_after_input_duration() { | 171 static base::TimeDelta maximum_idle_period_duration() { |
| 157 return base::TimeDelta::FromMilliseconds( | 172 return base::TimeDelta::FromMilliseconds( |
| 158 RendererSchedulerImpl::kPriorityEscalationAfterInputMillis); | 173 SchedulerHelper::kMaximumIdlePeriodMillis); |
| 159 } | 174 } |
| 160 | 175 |
| 161 static base::TimeDelta maximum_idle_period_duration() { | 176 base::TimeTicks CurrentIdleTaskDeadlineForTesting() { |
| 162 return base::TimeDelta::FromMilliseconds( | |
| 163 RendererSchedulerImpl::kMaximumIdlePeriodMillis); | |
| 164 } | |
| 165 | |
| 166 base::TimeTicks CurrentIdleTaskDeadline() { | |
| 167 base::TimeTicks deadline; | 177 base::TimeTicks deadline; |
| 168 scheduler_->CurrentIdleTaskDeadlineCallback(&deadline); | 178 scheduler_helper_->CurrentIdleTaskDeadlineCallback(&deadline); |
| 169 return deadline; | 179 return deadline; |
| 170 } | 180 } |
| 171 | 181 |
| 172 scoped_refptr<cc::TestNowSource> clock_; | 182 scoped_refptr<cc::TestNowSource> clock_; |
| 173 // Only one of mock_task_runner_ or message_loop_ will be set. | 183 // Only one of mock_task_runner_ or message_loop_ will be set. |
| 174 scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; | 184 scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; |
| 175 scoped_ptr<base::MessageLoop> message_loop_; | 185 scoped_ptr<base::MessageLoop> message_loop_; |
| 176 | 186 |
| 177 scoped_refptr<NestableSingleThreadTaskRunner> nestable_task_runner_; | 187 scoped_refptr<NestableSingleThreadTaskRunner> nestable_task_runner_; |
| 178 scoped_ptr<RendererSchedulerImpl> scheduler_; | 188 scoped_ptr<SchedulerHelperForTest> scheduler_helper_; |
| 179 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; | 189 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_; | 190 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_; |
| 183 | 191 |
| 184 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImplTest); | 192 DISALLOW_COPY_AND_ASSIGN(SchedulerHelperTest); |
| 185 }; | 193 }; |
| 186 | 194 |
| 187 void NullTask() { | 195 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; | 196 std::vector<std::string> run_order; |
| 265 PostTestTasks(&run_order, "D1 D2 D3 D4"); | 197 PostTestTasks(&run_order, "D1 D2 D3 D4"); |
| 266 | 198 |
| 267 RunUntilIdle(); | 199 RunUntilIdle(); |
| 268 EXPECT_THAT(run_order, | 200 EXPECT_THAT(run_order, |
| 269 testing::ElementsAre(std::string("D1"), std::string("D2"), | 201 testing::ElementsAre(std::string("D1"), std::string("D2"), |
| 270 std::string("D3"), std::string("D4"))); | 202 std::string("D3"), std::string("D4"))); |
| 271 } | 203 } |
| 272 | 204 |
| 273 TEST_F(RendererSchedulerImplTest, TestPostDefaultAndCompositor) { | 205 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; | 206 int count = 0; |
| 283 std::vector<int> run_order; | 207 std::vector<int> run_order; |
| 284 default_task_runner_->PostTask( | 208 default_task_runner_->PostTask( |
| 285 FROM_HERE, base::Bind(AppendToVectorReentrantTask, default_task_runner_, | 209 FROM_HERE, base::Bind(AppendToVectorReentrantTask, default_task_runner_, |
| 286 &run_order, &count, 5)); | 210 &run_order, &count, 5)); |
| 287 RunUntilIdle(); | 211 RunUntilIdle(); |
| 288 | 212 |
| 289 EXPECT_THAT(run_order, testing::ElementsAre(0, 1, 2, 3, 4)); | 213 EXPECT_THAT(run_order, testing::ElementsAre(0, 1, 2, 3, 4)); |
| 290 } | 214 } |
| 291 | 215 |
| 292 TEST_F(RendererSchedulerImplTest, TestPostIdleTask) { | 216 TEST_F(SchedulerHelperTest, TestPostIdleTask) { |
| 293 int run_count = 0; | 217 int run_count = 0; |
| 294 base::TimeTicks expected_deadline = | 218 base::TimeTicks expected_deadline = |
| 295 clock_->Now() + base::TimeDelta::FromMilliseconds(2300); | 219 clock_->Now() + base::TimeDelta::FromMilliseconds(2300); |
| 220 scheduler_helper_->SetEstimatedEndOfIdle(expected_deadline); | |
| 296 base::TimeTicks deadline_in_task; | 221 base::TimeTicks deadline_in_task; |
| 297 | 222 |
| 298 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(100)); | 223 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(100)); |
| 299 idle_task_runner_->PostIdleTask( | 224 idle_task_runner_->PostIdleTask( |
| 300 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); | 225 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); |
| 301 | 226 |
| 302 RunUntilIdle(); | 227 RunUntilIdle(); |
| 303 EXPECT_EQ(0, run_count); // Shouldn't run yet as no WillBeginFrame. | 228 EXPECT_EQ(0, run_count); |
| 304 | 229 |
| 305 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create( | 230 scheduler_helper_->StartIdlePeriod( |
| 306 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(), | 231 SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD); |
| 307 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL)); | |
| 308 RunUntilIdle(); | |
| 309 EXPECT_EQ(0, run_count); // Shouldn't run as no DidCommitFrameToCompositor. | |
| 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(); | 232 RunUntilIdle(); |
| 322 EXPECT_EQ(1, run_count); | 233 EXPECT_EQ(1, run_count); |
| 323 EXPECT_EQ(expected_deadline, deadline_in_task); | 234 EXPECT_EQ(expected_deadline, deadline_in_task); |
| 324 } | 235 } |
| 325 | 236 |
| 326 TEST_F(RendererSchedulerImplTest, TestRepostingIdleTask) { | 237 TEST_F(SchedulerHelperTest, TestPostIdleTask_EndIdlePeriod) { |
| 238 int run_count = 0; | |
| 239 base::TimeTicks deadline_in_task; | |
| 240 | |
| 241 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(100)); | |
| 242 idle_task_runner_->PostIdleTask( | |
| 243 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); | |
| 244 | |
| 245 RunUntilIdle(); | |
| 246 EXPECT_EQ(0, run_count); | |
| 247 | |
| 248 scheduler_helper_->StartIdlePeriod( | |
| 249 SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD); | |
| 250 scheduler_helper_->EndIdlePeriod(); | |
| 251 RunUntilIdle(); | |
| 252 EXPECT_EQ(0, run_count); | |
| 253 } | |
| 254 | |
| 255 TEST_F(SchedulerHelperTest, TestRepostingIdleTask) { | |
| 327 int run_count = 0; | 256 int run_count = 0; |
| 328 | 257 |
| 258 max_idle_task_reposts = 2; | |
| 329 idle_task_runner_->PostIdleTask( | 259 idle_task_runner_->PostIdleTask( |
| 330 FROM_HERE, | 260 FROM_HERE, |
| 331 base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count)); | 261 base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count)); |
| 332 EnableIdleTasks(); | 262 scheduler_helper_->StartIdlePeriod( |
| 263 SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD); | |
| 333 RunUntilIdle(); | 264 RunUntilIdle(); |
| 334 EXPECT_EQ(1, run_count); | 265 EXPECT_EQ(1, run_count); |
| 335 | 266 |
| 336 // Reposted tasks shouldn't run until next idle period. | 267 // Reposted tasks shouldn't run until next idle period. |
| 337 RunUntilIdle(); | 268 RunUntilIdle(); |
| 338 EXPECT_EQ(1, run_count); | 269 EXPECT_EQ(1, run_count); |
| 339 | 270 |
| 340 EnableIdleTasks(); | 271 scheduler_helper_->StartIdlePeriod( |
| 272 SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD); | |
| 341 RunUntilIdle(); | 273 RunUntilIdle(); |
| 342 EXPECT_EQ(2, run_count); | 274 EXPECT_EQ(2, run_count); |
| 343 } | 275 } |
| 344 | 276 |
| 345 TEST_F(RendererSchedulerImplTest, TestIdleTaskExceedsDeadline) { | 277 TEST_F(SchedulerHelperTest, TestPostIdleTaskAfterWakeup) { |
|
rmcilroy
2015/03/27 19:01:59
Please move this test here (SchedulerHelperUnittes
alex clarke (OOO till 29th)
2015/03/30 12:23:30
Done.
| |
| 346 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true); | |
| 347 int run_count = 0; | |
| 348 | |
| 349 // Post two UpdateClockToDeadlineIdleTestTask tasks. | |
| 350 idle_task_runner_->PostIdleTask( | |
| 351 FROM_HERE, base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_, | |
| 352 default_task_runner_, &run_count)); | |
| 353 idle_task_runner_->PostIdleTask( | |
| 354 FROM_HERE, base::Bind(&UpdateClockToDeadlineIdleTestTask, clock_, | |
| 355 default_task_runner_, &run_count)); | |
| 356 | |
| 357 EnableIdleTasks(); | |
| 358 RunUntilIdle(); | |
| 359 // Only the first idle task should execute since it's used up the deadline. | |
| 360 EXPECT_EQ(1, run_count); | |
| 361 | |
| 362 EnableIdleTasks(); | |
| 363 RunUntilIdle(); | |
| 364 // Second task should be run on the next idle period. | |
| 365 EXPECT_EQ(2, run_count); | |
| 366 } | |
| 367 | |
| 368 TEST_F(RendererSchedulerImplTest, TestPostIdleTaskAfterWakeup) { | |
| 369 base::TimeTicks deadline_in_task; | 278 base::TimeTicks deadline_in_task; |
| 370 int run_count = 0; | 279 int run_count = 0; |
| 371 | 280 |
| 372 idle_task_runner_->PostIdleTaskAfterWakeup( | 281 idle_task_runner_->PostIdleTaskAfterWakeup( |
| 373 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); | 282 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); |
| 374 | 283 |
| 375 EnableIdleTasks(); | 284 scheduler_helper_->StartIdlePeriod( |
| 285 SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD); | |
| 376 RunUntilIdle(); | 286 RunUntilIdle(); |
| 377 // Shouldn't run yet as no other task woke up the scheduler. | 287 // Shouldn't run yet as no other task woke up the scheduler. |
| 378 EXPECT_EQ(0, run_count); | 288 EXPECT_EQ(0, run_count); |
| 379 | 289 |
| 380 idle_task_runner_->PostIdleTaskAfterWakeup( | 290 idle_task_runner_->PostIdleTaskAfterWakeup( |
| 381 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); | 291 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); |
| 382 | 292 |
| 383 EnableIdleTasks(); | 293 scheduler_helper_->StartIdlePeriod( |
| 294 SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD); | |
| 384 RunUntilIdle(); | 295 RunUntilIdle(); |
| 385 // Another after wakeup idle task shouldn't wake the scheduler. | 296 // Another after wakeup idle task shouldn't wake the scheduler. |
| 386 EXPECT_EQ(0, run_count); | 297 EXPECT_EQ(0, run_count); |
| 387 | 298 |
| 388 default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask)); | 299 default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask)); |
| 389 | 300 |
| 390 RunUntilIdle(); | 301 RunUntilIdle(); |
| 391 EnableIdleTasks(); // Must start a new idle period before idle task runs. | 302 // Must start a new idle period before idle task runs. |
| 303 scheduler_helper_->StartIdlePeriod( | |
| 304 SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD); | |
| 392 RunUntilIdle(); | 305 RunUntilIdle(); |
| 393 // Execution of default task queue task should trigger execution of idle task. | 306 // Execution of default task queue task should trigger execution of idle task. |
| 394 EXPECT_EQ(2, run_count); | 307 EXPECT_EQ(2, run_count); |
| 395 } | 308 } |
| 396 | 309 |
| 397 TEST_F(RendererSchedulerImplTest, TestPostIdleTaskAfterWakeupWhileAwake) { | 310 TEST_F(SchedulerHelperTest, TestPostIdleTaskAfterWakeupWhileAwake) { |
| 398 base::TimeTicks deadline_in_task; | 311 base::TimeTicks deadline_in_task; |
| 399 int run_count = 0; | 312 int run_count = 0; |
| 400 | 313 |
| 401 idle_task_runner_->PostIdleTaskAfterWakeup( | 314 idle_task_runner_->PostIdleTaskAfterWakeup( |
| 402 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); | 315 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); |
| 403 default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask)); | 316 default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask)); |
| 404 | 317 |
| 405 RunUntilIdle(); | 318 RunUntilIdle(); |
| 406 EnableIdleTasks(); // Must start a new idle period before idle task runs. | 319 // Must start a new idle period before idle task runs. |
| 320 scheduler_helper_->StartIdlePeriod( | |
| 321 SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD); | |
| 407 RunUntilIdle(); | 322 RunUntilIdle(); |
| 408 // Should run as the scheduler was already awakened by the normal task. | 323 // Should run as the scheduler was already awakened by the normal task. |
| 409 EXPECT_EQ(1, run_count); | 324 EXPECT_EQ(1, run_count); |
| 410 } | 325 } |
| 411 | 326 |
| 412 TEST_F(RendererSchedulerImplTest, TestPostIdleTaskWakesAfterWakeupIdleTask) { | 327 TEST_F(SchedulerHelperTest, TestPostIdleTaskWakesAfterWakeupIdleTask) { |
| 413 base::TimeTicks deadline_in_task; | 328 base::TimeTicks deadline_in_task; |
| 414 int run_count = 0; | 329 int run_count = 0; |
| 415 | 330 |
| 416 idle_task_runner_->PostIdleTaskAfterWakeup( | 331 idle_task_runner_->PostIdleTaskAfterWakeup( |
| 417 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); | 332 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); |
| 418 idle_task_runner_->PostIdleTask( | 333 idle_task_runner_->PostIdleTask( |
| 419 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); | 334 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); |
| 420 | 335 |
| 421 EnableIdleTasks(); | 336 scheduler_helper_->StartIdlePeriod( |
| 337 SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD); | |
| 422 RunUntilIdle(); | 338 RunUntilIdle(); |
| 423 // Must start a new idle period before after-wakeup idle task runs. | 339 // Must start a new idle period before after-wakeup idle task runs. |
| 424 EnableIdleTasks(); | 340 scheduler_helper_->StartIdlePeriod( |
| 341 SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD); | |
| 425 RunUntilIdle(); | 342 RunUntilIdle(); |
| 426 // Normal idle task should wake up after-wakeup idle task. | 343 // Normal idle task should wake up after-wakeup idle task. |
| 427 EXPECT_EQ(2, run_count); | 344 EXPECT_EQ(2, run_count); |
| 428 } | 345 } |
| 429 | 346 |
| 430 TEST_F(RendererSchedulerImplTest, TestDelayedEndIdlePeriodCanceled) { | 347 class SchedulerHelperWithMessageLoopTest : public SchedulerHelperTest { |
| 431 int run_count = 0; | |
|
rmcilroy
2015/03/27 19:01:59
Could you add a test similar to this one (using st
alex clarke (OOO till 29th)
2015/03/30 12:23:30
Done. This was a bit of a pain, sadly there are o
| |
| 432 | |
| 433 base::TimeTicks deadline_in_task; | |
| 434 idle_task_runner_->PostIdleTask( | |
| 435 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); | |
| 436 | |
| 437 // Trigger the beginning of an idle period for 1000ms. | |
| 438 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create( | |
| 439 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(), | |
| 440 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL)); | |
| 441 DoMainFrame(); | |
| 442 | |
| 443 // End the idle period early (after 500ms), and send a WillBeginFrame which | |
| 444 // specifies that the next idle period should end 1000ms from now. | |
| 445 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(500)); | |
| 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: | 348 public: |
| 912 RendererSchedulerImplForTest( | 349 SchedulerHelperWithMessageLoopTest() |
| 913 scoped_refptr<NestableSingleThreadTaskRunner> main_task_runner) | 350 : SchedulerHelperTest(new base::MessageLoop()) {} |
| 914 : RendererSchedulerImpl(main_task_runner), update_policy_count_(0) {} | 351 ~SchedulerHelperWithMessageLoopTest() override {} |
| 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 | |
| 934 RunUntilIdle(); | |
| 935 | |
| 936 EXPECT_EQ(1, mock_scheduler->update_policy_count_); | |
| 937 } | |
| 938 | |
| 939 TEST_F(RendererSchedulerImplTest, OnePendingDelayedAndOneUrgentUpdatePolicy) { | |
| 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); | |
| 945 | |
| 946 ScheduleDelayedPolicyUpdate(base::TimeDelta::FromMilliseconds(1)); | |
| 947 EnsureUrgentPolicyUpdatePostedOnMainThread(); | |
| 948 | |
| 949 RunUntilIdle(); | |
| 950 | |
| 951 // We expect both the urgent and the delayed updates to run. | |
| 952 EXPECT_EQ(2, mock_scheduler->update_policy_count_); | |
| 953 } | |
| 954 | |
| 955 TEST_F(RendererSchedulerImplTest, OneUrgentAndOnePendingDelayedUpdatePolicy) { | |
| 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: | |
| 1043 RendererSchedulerImplWithMessageLoopTest() | |
| 1044 : RendererSchedulerImplTest(new base::MessageLoop()) {} | |
| 1045 ~RendererSchedulerImplWithMessageLoopTest() override {} | |
| 1046 | 352 |
| 1047 void PostFromNestedRunloop(std::vector< | 353 void PostFromNestedRunloop(std::vector< |
| 1048 std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>>* tasks) { | 354 std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>>* tasks) { |
| 1049 base::MessageLoop::ScopedNestableTaskAllower allow(message_loop_.get()); | 355 base::MessageLoop::ScopedNestableTaskAllower allow(message_loop_.get()); |
| 1050 for (std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>& pair : *tasks) { | 356 for (std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>& pair : *tasks) { |
| 1051 if (pair.second) { | 357 if (pair.second) { |
| 1052 idle_task_runner_->PostIdleTask(FROM_HERE, pair.first); | 358 idle_task_runner_->PostIdleTask(FROM_HERE, pair.first); |
| 1053 } else { | 359 } else { |
| 1054 idle_task_runner_->PostNonNestableIdleTask(FROM_HERE, pair.first); | 360 idle_task_runner_->PostNonNestableIdleTask(FROM_HERE, pair.first); |
| 1055 } | 361 } |
| 1056 } | 362 } |
| 1057 EnableIdleTasks(); | 363 scheduler_helper_->StartIdlePeriod( |
| 364 SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD); | |
| 1058 message_loop_->RunUntilIdle(); | 365 message_loop_->RunUntilIdle(); |
| 1059 } | 366 } |
| 1060 | 367 |
| 1061 private: | 368 private: |
| 1062 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerImplWithMessageLoopTest); | 369 DISALLOW_COPY_AND_ASSIGN(SchedulerHelperWithMessageLoopTest); |
| 1063 }; | 370 }; |
| 1064 | 371 |
| 1065 TEST_F(RendererSchedulerImplWithMessageLoopTest, | 372 TEST_F(SchedulerHelperWithMessageLoopTest, |
| 1066 NonNestableIdleTaskDoesntExecuteInNestedLoop) { | 373 NonNestableIdleTaskDoesntExecuteInNestedLoop) { |
| 1067 std::vector<std::string> order; | 374 std::vector<std::string> order; |
| 1068 idle_task_runner_->PostIdleTask( | 375 idle_task_runner_->PostIdleTask( |
| 1069 FROM_HERE, | 376 FROM_HERE, |
| 1070 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("1"))); | 377 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("1"))); |
| 1071 idle_task_runner_->PostIdleTask( | 378 idle_task_runner_->PostIdleTask( |
| 1072 FROM_HERE, | 379 FROM_HERE, |
| 1073 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("2"))); | 380 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("2"))); |
| 1074 | 381 |
| 1075 std::vector<std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>> | 382 std::vector<std::pair<SingleThreadIdleTaskRunner::IdleTask, bool>> |
| 1076 tasks_to_post_from_nested_loop; | 383 tasks_to_post_from_nested_loop; |
| 1077 tasks_to_post_from_nested_loop.push_back(std::make_pair( | 384 tasks_to_post_from_nested_loop.push_back(std::make_pair( |
| 1078 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("3")), | 385 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("3")), |
| 1079 false)); | 386 false)); |
| 1080 tasks_to_post_from_nested_loop.push_back(std::make_pair( | 387 tasks_to_post_from_nested_loop.push_back(std::make_pair( |
| 1081 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("4")), true)); | 388 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("4")), true)); |
| 1082 tasks_to_post_from_nested_loop.push_back(std::make_pair( | 389 tasks_to_post_from_nested_loop.push_back(std::make_pair( |
| 1083 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("5")), true)); | 390 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("5")), true)); |
| 1084 | 391 |
| 1085 default_task_runner_->PostTask( | 392 default_task_runner_->PostTask( |
| 1086 FROM_HERE, | 393 FROM_HERE, |
| 1087 base::Bind( | 394 base::Bind(&SchedulerHelperWithMessageLoopTest::PostFromNestedRunloop, |
| 1088 &RendererSchedulerImplWithMessageLoopTest::PostFromNestedRunloop, | 395 base::Unretained(this), |
| 1089 base::Unretained(this), | 396 base::Unretained(&tasks_to_post_from_nested_loop))); |
| 1090 base::Unretained(&tasks_to_post_from_nested_loop))); | |
| 1091 | 397 |
| 1092 EnableIdleTasks(); | 398 scheduler_helper_->StartIdlePeriod( |
| 399 SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD); | |
| 1093 RunUntilIdle(); | 400 RunUntilIdle(); |
| 1094 // Note we expect task 3 to run last because it's non-nestable. | 401 // 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"), | 402 EXPECT_THAT(order, testing::ElementsAre(std::string("1"), std::string("2"), |
| 1096 std::string("4"), std::string("5"), | 403 std::string("4"), std::string("5"), |
| 1097 std::string("3"))); | 404 std::string("3"))); |
| 1098 } | 405 } |
| 1099 | 406 |
| 1100 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriod) { | 407 TEST_F(SchedulerHelperTest, TestLongIdlePeriod) { |
| 1101 base::TimeTicks expected_deadline = | 408 base::TimeTicks expected_deadline = |
| 1102 clock_->Now() + maximum_idle_period_duration(); | 409 clock_->Now() + maximum_idle_period_duration(); |
| 1103 base::TimeTicks deadline_in_task; | 410 base::TimeTicks deadline_in_task; |
| 1104 int run_count = 0; | 411 int run_count = 0; |
| 1105 | 412 |
| 1106 idle_task_runner_->PostIdleTask( | 413 idle_task_runner_->PostIdleTask( |
| 1107 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); | 414 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); |
| 1108 | 415 |
| 416 EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _)) | |
| 417 .Times(2) | |
| 418 .WillRepeatedly(Return(true)); | |
| 419 | |
| 1109 RunUntilIdle(); | 420 RunUntilIdle(); |
| 1110 EXPECT_EQ(0, run_count); // Shouldn't run yet as no idle period. | 421 EXPECT_EQ(0, run_count); // Shouldn't run yet as no idle period. |
| 1111 | 422 |
| 1112 scheduler_->BeginFrameNotExpectedSoon(); | 423 scheduler_helper_->InitiateLongIdlePeriod(); |
| 1113 RunUntilIdle(); | 424 RunUntilIdle(); |
| 1114 EXPECT_EQ(1, run_count); // Should have run in a long idle time. | 425 EXPECT_EQ(1, run_count); // Should have run in a long idle time. |
| 1115 EXPECT_EQ(expected_deadline, deadline_in_task); | 426 EXPECT_EQ(expected_deadline, deadline_in_task); |
| 1116 } | 427 } |
| 1117 | 428 |
| 1118 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodWithPendingDelayedTask) { | 429 TEST_F(SchedulerHelperTest, TestLongIdlePeriodWithPendingDelayedTask) { |
| 1119 base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(30); | 430 base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(30); |
| 1120 base::TimeTicks expected_deadline = clock_->Now() + pending_task_delay; | 431 base::TimeTicks expected_deadline = clock_->Now() + pending_task_delay; |
| 1121 base::TimeTicks deadline_in_task; | 432 base::TimeTicks deadline_in_task; |
| 1122 int run_count = 0; | 433 int run_count = 0; |
| 1123 | 434 |
| 435 EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _)) | |
| 436 .Times(2) | |
| 437 .WillRepeatedly(Return(true)); | |
| 438 | |
| 1124 idle_task_runner_->PostIdleTask( | 439 idle_task_runner_->PostIdleTask( |
| 1125 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); | 440 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); |
| 1126 default_task_runner_->PostDelayedTask( | 441 default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask), |
| 1127 FROM_HERE, base::Bind(&NullTask), pending_task_delay); | 442 pending_task_delay); |
| 1128 | 443 |
| 1129 scheduler_->BeginFrameNotExpectedSoon(); | 444 scheduler_helper_->InitiateLongIdlePeriod(); |
| 1130 RunUntilIdle(); | 445 RunUntilIdle(); |
| 1131 EXPECT_EQ(1, run_count); // Should have run in a long idle time. | 446 EXPECT_EQ(1, run_count); // Should have run in a long idle time. |
| 1132 EXPECT_EQ(expected_deadline, deadline_in_task); | 447 EXPECT_EQ(expected_deadline, deadline_in_task); |
| 1133 } | 448 } |
| 1134 | 449 |
| 1135 TEST_F(RendererSchedulerImplTest, | 450 TEST_F(SchedulerHelperTest, TestLongIdlePeriodWithLatePendingDelayedTask) { |
| 1136 TestLongIdlePeriodWithLatePendingDelayedTask) { | |
| 1137 base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(10); | 451 base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(10); |
| 1138 base::TimeTicks deadline_in_task; | 452 base::TimeTicks deadline_in_task; |
| 1139 int run_count = 0; | 453 int run_count = 0; |
| 1140 | 454 |
| 1141 default_task_runner_->PostDelayedTask( | 455 EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _)) |
| 1142 FROM_HERE, base::Bind(&NullTask), pending_task_delay); | 456 .Times(3) |
| 457 .WillRepeatedly(Return(true)); | |
| 458 | |
| 459 default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask), | |
| 460 pending_task_delay); | |
| 1143 | 461 |
| 1144 // Advance clock until after delayed task was meant to be run. | 462 // Advance clock until after delayed task was meant to be run. |
| 1145 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(20)); | 463 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(20)); |
| 1146 | 464 |
| 1147 // Post an idle task and BeginFrameNotExpectedSoon to initiate a long idle | 465 // 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 | 466 // pending delayed task this shouldn't actually start an idle period. |
| 1149 // start an idle period. | |
| 1150 idle_task_runner_->PostIdleTask( | 467 idle_task_runner_->PostIdleTask( |
| 1151 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); | 468 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); |
| 1152 scheduler_->BeginFrameNotExpectedSoon(); | 469 scheduler_helper_->InitiateLongIdlePeriod(); |
| 1153 RunUntilIdle(); | 470 RunUntilIdle(); |
| 1154 EXPECT_EQ(0, run_count); | 471 EXPECT_EQ(0, run_count); |
| 1155 | 472 |
| 1156 // After the delayed task has been run we should trigger an idle period. | 473 // After the delayed task has been run we should trigger an idle period. |
| 1157 clock_->AdvanceNow(maximum_idle_period_duration()); | 474 clock_->AdvanceNow(maximum_idle_period_duration()); |
| 1158 RunUntilIdle(); | 475 RunUntilIdle(); |
| 1159 EXPECT_EQ(1, run_count); | 476 EXPECT_EQ(1, run_count); |
| 1160 } | 477 } |
| 1161 | 478 |
| 1162 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodRepeating) { | 479 TEST_F(SchedulerHelperTest, TestLongIdlePeriodRepeating) { |
| 1163 int run_count = 0; | 480 int run_count = 0; |
| 1164 | 481 |
| 482 EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _)) | |
| 483 .Times(4) | |
| 484 .WillRepeatedly(Return(true)); | |
| 485 | |
| 486 max_idle_task_reposts = 3; | |
| 1165 idle_task_runner_->PostIdleTask( | 487 idle_task_runner_->PostIdleTask( |
| 1166 FROM_HERE, | 488 FROM_HERE, |
| 1167 base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count)); | 489 base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count)); |
| 1168 | 490 |
| 1169 scheduler_->BeginFrameNotExpectedSoon(); | 491 scheduler_helper_->InitiateLongIdlePeriod(); |
| 1170 RunUntilIdle(); | 492 RunUntilIdle(); |
| 1171 EXPECT_EQ(1, run_count); // Should only run once per idle period. | 493 EXPECT_EQ(1, run_count); // Should only run once per idle period. |
| 1172 | 494 |
| 1173 // Advance time to start of next long idle period and check task reposted task | 495 // Advance time to start of next long idle period and check task reposted task |
| 1174 // gets run. | 496 // gets run. |
| 1175 clock_->AdvanceNow(maximum_idle_period_duration()); | 497 clock_->AdvanceNow(maximum_idle_period_duration()); |
| 1176 RunUntilIdle(); | 498 RunUntilIdle(); |
| 1177 EXPECT_EQ(2, run_count); | 499 EXPECT_EQ(2, run_count); |
| 1178 | 500 |
| 1179 // Advance time to start of next long idle period then end idle period with a | 501 // Advance time to start of next long idle period and check task reposted task |
| 1180 // new BeginMainFrame and check idle task doesn't run. | 502 // gets run. |
| 1181 clock_->AdvanceNow(maximum_idle_period_duration()); | 503 clock_->AdvanceNow(maximum_idle_period_duration()); |
|
rmcilroy
2015/03/27 19:01:59
Please make this do the same as the previous test
alex clarke (OOO till 29th)
2015/03/30 12:23:30
Done.
| |
| 1182 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create( | |
| 1183 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(), | |
| 1184 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL)); | |
| 1185 RunUntilIdle(); | 504 RunUntilIdle(); |
| 1186 EXPECT_EQ(2, run_count); | 505 EXPECT_EQ(3, run_count); |
| 1187 } | 506 } |
| 1188 | 507 |
| 1189 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodDoesNotWakeScheduler) { | 508 TEST_F(SchedulerHelperTest, TestLongIdlePeriodDoesNotWakeScheduler) { |
| 1190 base::TimeTicks deadline_in_task; | 509 base::TimeTicks deadline_in_task; |
| 1191 int run_count = 0; | 510 int run_count = 0; |
| 1192 | 511 |
| 512 EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _)) | |
| 513 .Times(3) | |
| 514 .WillRepeatedly(Return(true)); | |
| 515 | |
| 1193 // Start a long idle period and get the time it should end. | 516 // Start a long idle period and get the time it should end. |
| 1194 scheduler_->BeginFrameNotExpectedSoon(); | 517 scheduler_helper_->InitiateLongIdlePeriod(); |
| 1195 // The scheduler should not run the initiate_next_long_idle_period task if | 518 // 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 | 519 // 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 | 520 // the idle period deadline shouldn't update at the end of the current long |
| 1198 // idle period. | 521 // idle period. |
| 1199 base::TimeTicks idle_period_deadline = CurrentIdleTaskDeadline(); | 522 base::TimeTicks idle_period_deadline = CurrentIdleTaskDeadlineForTesting(); |
| 1200 clock_->AdvanceNow(maximum_idle_period_duration()); | 523 clock_->AdvanceNow(maximum_idle_period_duration()); |
| 1201 RunUntilIdle(); | 524 RunUntilIdle(); |
| 1202 | 525 |
| 1203 base::TimeTicks new_idle_period_deadline = CurrentIdleTaskDeadline(); | 526 base::TimeTicks new_idle_period_deadline = |
| 527 CurrentIdleTaskDeadlineForTesting(); | |
| 1204 EXPECT_EQ(idle_period_deadline, new_idle_period_deadline); | 528 EXPECT_EQ(idle_period_deadline, new_idle_period_deadline); |
| 1205 | 529 |
| 1206 // Posting a after-wakeup idle task also shouldn't wake the scheduler or | 530 // Posting a after-wakeup idle task also shouldn't wake the scheduler or |
| 1207 // initiate the next long idle period. | 531 // initiate the next long idle period. |
| 1208 idle_task_runner_->PostIdleTaskAfterWakeup( | 532 idle_task_runner_->PostIdleTaskAfterWakeup( |
| 1209 FROM_HERE, | 533 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); |
| 1210 base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); | |
| 1211 RunUntilIdle(); | 534 RunUntilIdle(); |
| 1212 new_idle_period_deadline = CurrentIdleTaskDeadline(); | 535 new_idle_period_deadline = CurrentIdleTaskDeadlineForTesting(); |
| 1213 EXPECT_EQ(idle_period_deadline, new_idle_period_deadline); | 536 EXPECT_EQ(idle_period_deadline, new_idle_period_deadline); |
| 1214 EXPECT_EQ(0, run_count); | 537 EXPECT_EQ(0, run_count); |
| 1215 | 538 |
| 1216 // Running a normal task should initiate a new long idle period though. | 539 // Running a normal task should initiate a new long idle period though. |
| 1217 default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask)); | 540 default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask)); |
| 1218 RunUntilIdle(); | 541 RunUntilIdle(); |
| 1219 new_idle_period_deadline = CurrentIdleTaskDeadline(); | 542 new_idle_period_deadline = CurrentIdleTaskDeadlineForTesting(); |
| 1220 EXPECT_EQ(idle_period_deadline + maximum_idle_period_duration(), | 543 EXPECT_EQ(idle_period_deadline + maximum_idle_period_duration(), |
| 1221 new_idle_period_deadline); | 544 new_idle_period_deadline); |
| 1222 | 545 |
| 1223 EXPECT_EQ(1, run_count); | 546 EXPECT_EQ(1, run_count); |
| 1224 } | 547 } |
| 1225 | 548 |
| 1226 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodInTouchStartPolicy) { | 549 TEST_F(SchedulerHelperTest, TestLongIdlePeriodCantEnterLongIdlePeriod) { |
|
rmcilroy
2015/03/27 19:01:59
nit - TestLongIdlePeriodWhenNotCanEnterLongIdlePer
alex clarke (OOO till 29th)
2015/03/30 12:23:30
Done.
| |
| 550 base::TimeDelta delay = base::TimeDelta::FromMilliseconds(1000); | |
| 551 base::TimeDelta halfDelay = base::TimeDelta::FromMilliseconds(500); | |
| 552 base::TimeTicks delayOver = clock_->Now() + delay; | |
| 1227 base::TimeTicks deadline_in_task; | 553 base::TimeTicks deadline_in_task; |
| 1228 int run_count = 0; | 554 int run_count = 0; |
| 1229 | 555 |
| 556 ON_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _)) | |
| 557 .WillByDefault(Invoke([&delay, &delayOver]( | |
| 558 base::TimeTicks now, | |
| 559 base::TimeDelta* next_long_idle_period_delay_out) { | |
| 560 if (now >= delayOver) | |
| 561 return true; | |
| 562 *next_long_idle_period_delay_out = delay; | |
| 563 return false; | |
| 564 })); | |
| 565 | |
| 566 EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _)).Times(3); | |
| 567 | |
| 1230 idle_task_runner_->PostIdleTask( | 568 idle_task_runner_->PostIdleTask( |
| 1231 FROM_HERE, | 569 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); |
| 1232 base::Bind(&IdleTestTask, &run_count, &deadline_in_task)); | |
| 1233 | 570 |
| 1234 // Observation of touchstart should defer the start of the long idle period. | 571 // Make sure Idle tasks don't run until the delay has occured. |
| 1235 scheduler_->DidReceiveInputEventOnCompositorThread( | 572 scheduler_helper_->InitiateLongIdlePeriod(); |
| 1236 FakeInputEvent(blink::WebInputEvent::TouchStart)); | |
| 1237 scheduler_->BeginFrameNotExpectedSoon(); | |
| 1238 RunUntilIdle(); | 573 RunUntilIdle(); |
| 1239 EXPECT_EQ(0, run_count); | 574 EXPECT_EQ(0, run_count); |
| 1240 | 575 |
| 1241 // The long idle period should start after the touchstart policy has finished. | 576 clock_->AdvanceNow(halfDelay); |
| 1242 clock_->AdvanceNow(priority_escalation_after_input_duration()); | 577 RunUntilIdle(); |
| 578 EXPECT_EQ(0, run_count); | |
| 579 | |
| 580 // Delay is finished, idle task should run. | |
| 581 clock_->AdvanceNow(halfDelay); | |
| 1243 RunUntilIdle(); | 582 RunUntilIdle(); |
| 1244 EXPECT_EQ(1, run_count); | 583 EXPECT_EQ(1, run_count); |
| 1245 } | 584 } |
| 1246 | 585 |
| 1247 void TestCanExceedIdleDeadlineIfRequiredTask(RendererScheduler* scheduler, | 586 void TestCanExceedIdleDeadlineIfRequiredTask(SchedulerHelperForTest* scheduler, |
| 1248 bool* can_exceed_idle_deadline_out, | 587 bool* can_exceed_idle_deadline_out, |
| 1249 int* run_count, | 588 int* run_count, |
| 1250 base::TimeTicks deadline) { | 589 base::TimeTicks deadline) { |
| 1251 *can_exceed_idle_deadline_out = scheduler->CanExceedIdleDeadlineIfRequired(); | 590 *can_exceed_idle_deadline_out = scheduler->CanExceedIdleDeadlineIfRequired(); |
| 1252 (*run_count)++; | 591 (*run_count)++; |
| 1253 } | 592 } |
| 1254 | 593 |
| 1255 TEST_F(RendererSchedulerImplTest, CanExceedIdleDeadlineIfRequired) { | 594 TEST_F(SchedulerHelperTest, CanExceedIdleDeadlineIfRequired) { |
| 1256 int run_count = 0; | 595 int run_count = 0; |
| 1257 bool can_exceed_idle_deadline = false; | 596 bool can_exceed_idle_deadline = false; |
| 1258 | 597 |
| 598 EXPECT_CALL(*scheduler_helper_, CanEnterLongIdlePeriod(_, _)) | |
| 599 .Times(3) | |
| 600 .WillRepeatedly(Return(true)); | |
| 601 | |
| 1259 // Should return false if not in an idle period. | 602 // Should return false if not in an idle period. |
| 1260 EXPECT_FALSE(scheduler_->CanExceedIdleDeadlineIfRequired()); | 603 EXPECT_FALSE(scheduler_helper_->CanExceedIdleDeadlineIfRequired()); |
| 1261 | 604 |
| 1262 // Should return false for short idle periods. | 605 // Should return false for short idle periods. |
| 1263 idle_task_runner_->PostIdleTask( | 606 idle_task_runner_->PostIdleTask( |
| 1264 FROM_HERE, | 607 FROM_HERE, base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, |
| 1265 base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(), | 608 scheduler_helper_.get(), &can_exceed_idle_deadline, |
| 1266 &can_exceed_idle_deadline, &run_count)); | 609 &run_count)); |
| 1267 EnableIdleTasks(); | 610 scheduler_helper_->StartIdlePeriod( |
| 611 SchedulerHelperForTest::IdlePeriodState::IN_SHORT_IDLE_PERIOD); | |
| 1268 RunUntilIdle(); | 612 RunUntilIdle(); |
| 1269 EXPECT_EQ(1, run_count); | 613 EXPECT_EQ(1, run_count); |
| 1270 EXPECT_FALSE(can_exceed_idle_deadline); | 614 EXPECT_FALSE(can_exceed_idle_deadline); |
| 1271 | 615 |
| 1272 // Should return false for a long idle period which is shortened due to a | 616 // Should return false for a long idle period which is shortened due to a |
| 1273 // pending delayed task. | 617 // pending delayed task. |
| 1274 default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask), | 618 default_task_runner_->PostDelayedTask(FROM_HERE, base::Bind(&NullTask), |
| 1275 base::TimeDelta::FromMilliseconds(10)); | 619 base::TimeDelta::FromMilliseconds(10)); |
| 1276 idle_task_runner_->PostIdleTask( | 620 idle_task_runner_->PostIdleTask( |
| 1277 FROM_HERE, | 621 FROM_HERE, base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, |
| 1278 base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(), | 622 scheduler_helper_.get(), &can_exceed_idle_deadline, |
| 1279 &can_exceed_idle_deadline, &run_count)); | 623 &run_count)); |
| 1280 scheduler_->BeginFrameNotExpectedSoon(); | 624 scheduler_helper_->InitiateLongIdlePeriod(); |
| 1281 RunUntilIdle(); | 625 RunUntilIdle(); |
| 1282 EXPECT_EQ(2, run_count); | 626 EXPECT_EQ(2, run_count); |
| 1283 EXPECT_FALSE(can_exceed_idle_deadline); | 627 EXPECT_FALSE(can_exceed_idle_deadline); |
| 1284 | 628 |
| 1285 // Next long idle period will be for the maximum time, so | 629 // Next long idle period will be for the maximum time, so |
| 1286 // CanExceedIdleDeadlineIfRequired should return true. | 630 // CanExceedIdleDeadlineIfRequired should return true. |
| 1287 clock_->AdvanceNow(maximum_idle_period_duration()); | 631 clock_->AdvanceNow(maximum_idle_period_duration()); |
| 1288 idle_task_runner_->PostIdleTask( | 632 idle_task_runner_->PostIdleTask( |
| 1289 FROM_HERE, | 633 FROM_HERE, base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, |
| 1290 base::Bind(&TestCanExceedIdleDeadlineIfRequiredTask, scheduler_.get(), | 634 scheduler_helper_.get(), &can_exceed_idle_deadline, |
| 1291 &can_exceed_idle_deadline, &run_count)); | 635 &run_count)); |
| 1292 RunUntilIdle(); | 636 RunUntilIdle(); |
| 1293 EXPECT_EQ(3, run_count); | 637 EXPECT_EQ(3, run_count); |
| 1294 EXPECT_TRUE(can_exceed_idle_deadline); | 638 EXPECT_TRUE(can_exceed_idle_deadline); |
| 639 } | |
| 1295 | 640 |
| 1296 // Next long idle period will be for the maximum time, so | 641 TEST_F(SchedulerHelperTest, IsShutdown) { |
| 1297 // CanExceedIdleDeadlineIfRequired should return true. | 642 EXPECT_FALSE(scheduler_helper_->IsShutdown()); |
| 1298 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create( | 643 |
| 1299 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(), | 644 scheduler_helper_->Shutdown(); |
| 1300 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL)); | 645 EXPECT_TRUE(scheduler_helper_->IsShutdown()); |
| 1301 EXPECT_FALSE(scheduler_->CanExceedIdleDeadlineIfRequired()); | |
| 1302 } | 646 } |
| 1303 | 647 |
| 1304 } // namespace content | 648 } // namespace content |
| OLD | NEW |