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

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

Issue 968073003: [content]: Add support for long idle times in the Blink Scheduler. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@long_idle_4
Patch Set: Enable for testing Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/renderer/scheduler/renderer_scheduler_impl.h"
6 6
7 #include "base/callback.h" 7 #include "base/callback.h"
8 #include "cc/output/begin_frame_args.h" 8 #include "cc/output/begin_frame_args.h"
9 #include "cc/test/ordered_simple_task_runner.h" 9 #include "cc/test/ordered_simple_task_runner.h"
10 #include "content/renderer/scheduler/nestable_task_runner_for_test.h" 10 #include "content/renderer/scheduler/nestable_task_runner_for_test.h"
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 : clock_(cc::TestNowSource::Create(5000)), 50 : clock_(cc::TestNowSource::Create(5000)),
51 mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_, false)), 51 mock_task_runner_(new cc::OrderedSimpleTaskRunner(clock_, false)),
52 nestable_task_runner_( 52 nestable_task_runner_(
53 NestableTaskRunnerForTest::Create(mock_task_runner_)), 53 NestableTaskRunnerForTest::Create(mock_task_runner_)),
54 scheduler_(new RendererSchedulerImpl(nestable_task_runner_)), 54 scheduler_(new RendererSchedulerImpl(nestable_task_runner_)),
55 default_task_runner_(scheduler_->DefaultTaskRunner()), 55 default_task_runner_(scheduler_->DefaultTaskRunner()),
56 compositor_task_runner_(scheduler_->CompositorTaskRunner()), 56 compositor_task_runner_(scheduler_->CompositorTaskRunner()),
57 loading_task_runner_(scheduler_->LoadingTaskRunner()), 57 loading_task_runner_(scheduler_->LoadingTaskRunner()),
58 idle_task_runner_(scheduler_->IdleTaskRunner()) { 58 idle_task_runner_(scheduler_->IdleTaskRunner()) {
59 scheduler_->SetTimeSourceForTesting(clock_); 59 scheduler_->SetTimeSourceForTesting(clock_);
60 scheduler_->SetLongIdlePeriodsEnabledForTesting(true);
60 } 61 }
61 62
62 RendererSchedulerImplTest(base::MessageLoop* message_loop) 63 RendererSchedulerImplTest(base::MessageLoop* message_loop)
63 : clock_(cc::TestNowSource::Create(5000)), 64 : clock_(cc::TestNowSource::Create(5000)),
64 message_loop_(message_loop), 65 message_loop_(message_loop),
65 nestable_task_runner_( 66 nestable_task_runner_(
66 RendererSchedulerMessageLoopDelegate::Create(message_loop)), 67 RendererSchedulerMessageLoopDelegate::Create(message_loop)),
67 scheduler_(new RendererSchedulerImpl(nestable_task_runner_)), 68 scheduler_(new RendererSchedulerImpl(nestable_task_runner_)),
68 default_task_runner_(scheduler_->DefaultTaskRunner()), 69 default_task_runner_(scheduler_->DefaultTaskRunner()),
69 compositor_task_runner_(scheduler_->CompositorTaskRunner()), 70 compositor_task_runner_(scheduler_->CompositorTaskRunner()),
70 loading_task_runner_(scheduler_->LoadingTaskRunner()), 71 loading_task_runner_(scheduler_->LoadingTaskRunner()),
71 idle_task_runner_(scheduler_->IdleTaskRunner()) { 72 idle_task_runner_(scheduler_->IdleTaskRunner()) {
72 scheduler_->SetTimeSourceForTesting(clock_); 73 scheduler_->SetTimeSourceForTesting(clock_);
74 scheduler_->SetLongIdlePeriodsEnabledForTesting(true);
73 } 75 }
74 ~RendererSchedulerImplTest() override {} 76 ~RendererSchedulerImplTest() override {}
75 77
76 void TearDown() override { 78 void TearDown() override {
77 DCHECK(!mock_task_runner_.get() || !message_loop_.get()); 79 DCHECK(!mock_task_runner_.get() || !message_loop_.get());
78 if (mock_task_runner_.get()) { 80 if (mock_task_runner_.get()) {
79 // Check that all tests stop posting tasks. 81 // Check that all tests stop posting tasks.
80 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true); 82 mock_task_runner_->SetAutoAdvanceNowToPendingTasks(true);
81 while (mock_task_runner_->RunUntilIdle()) { 83 while (mock_task_runner_->RunUntilIdle()) {
82 } 84 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 } 153 }
152 } 154 }
153 } 155 }
154 156
155 protected: 157 protected:
156 static base::TimeDelta priority_escalation_after_input_duration() { 158 static base::TimeDelta priority_escalation_after_input_duration() {
157 return base::TimeDelta::FromMilliseconds( 159 return base::TimeDelta::FromMilliseconds(
158 RendererSchedulerImpl::kPriorityEscalationAfterInputMillis); 160 RendererSchedulerImpl::kPriorityEscalationAfterInputMillis);
159 } 161 }
160 162
163 static base::TimeDelta maximum_idle_period_duration() {
164 return base::TimeDelta::FromMilliseconds(
165 RendererSchedulerImpl::kMaximumIdlePeriodMillis);
166 }
167
168 base::TimeTicks CurrentIdleTaskDeadline() {
169 base::TimeTicks deadline;
170 scheduler_->CurrentIdleTaskDeadlineCallback(&deadline);
171 return deadline;
172 }
173
161 scoped_refptr<cc::TestNowSource> clock_; 174 scoped_refptr<cc::TestNowSource> clock_;
162 // Only one of mock_task_runner_ or message_loop_ will be set. 175 // Only one of mock_task_runner_ or message_loop_ will be set.
163 scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_; 176 scoped_refptr<cc::OrderedSimpleTaskRunner> mock_task_runner_;
164 scoped_ptr<base::MessageLoop> message_loop_; 177 scoped_ptr<base::MessageLoop> message_loop_;
165 178
166 scoped_refptr<NestableSingleThreadTaskRunner> nestable_task_runner_; 179 scoped_refptr<NestableSingleThreadTaskRunner> nestable_task_runner_;
167 scoped_ptr<RendererSchedulerImpl> scheduler_; 180 scoped_ptr<RendererSchedulerImpl> scheduler_;
168 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_; 181 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
169 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_; 182 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
170 scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_; 183 scoped_refptr<base::SingleThreadTaskRunner> loading_task_runner_;
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 EXPECT_THAT(run_order, 502 EXPECT_THAT(run_order,
490 testing::ElementsAre(std::string("C1"), std::string("C2"), 503 testing::ElementsAre(std::string("C1"), std::string("C2"),
491 std::string("D1"), std::string("D2"), 504 std::string("D1"), std::string("D2"),
492 std::string("I1"))); 505 std::string("I1")));
493 } 506 }
494 507
495 TEST_F(RendererSchedulerImplTest, TestTouchstartPolicy) { 508 TEST_F(RendererSchedulerImplTest, TestTouchstartPolicy) {
496 std::vector<std::string> run_order; 509 std::vector<std::string> run_order;
497 PostTestTasks(&run_order, "L1 D1 C1 D2 C2"); 510 PostTestTasks(&run_order, "L1 D1 C1 D2 C2");
498 511
499 // Observation of touchstart should defer execution of idle and loading tasks. 512 // Observation of touchstart should defer execution of loading tasks.
500 scheduler_->DidReceiveInputEventOnCompositorThread( 513 scheduler_->DidReceiveInputEventOnCompositorThread(
501 FakeInputEvent(blink::WebInputEvent::TouchStart)); 514 FakeInputEvent(blink::WebInputEvent::TouchStart));
502 RunUntilIdle(); 515 RunUntilIdle();
503 EXPECT_THAT(run_order, 516 EXPECT_THAT(run_order,
504 testing::ElementsAre(std::string("C1"), std::string("C2"), 517 testing::ElementsAre(std::string("C1"), std::string("C2"),
505 std::string("D1"), std::string("D2"))); 518 std::string("D1"), std::string("D2")));
506 519
507 // Meta events like TapDown/FlingCancel shouldn't affect the priority. 520 // Meta events like TapDown/FlingCancel shouldn't affect the priority.
508 run_order.clear(); 521 run_order.clear();
509 scheduler_->DidReceiveInputEventOnCompositorThread( 522 scheduler_->DidReceiveInputEventOnCompositorThread(
(...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after
1079 base::Unretained(&tasks_to_post_from_nested_loop))); 1092 base::Unretained(&tasks_to_post_from_nested_loop)));
1080 1093
1081 EnableIdleTasks(); 1094 EnableIdleTasks();
1082 RunUntilIdle(); 1095 RunUntilIdle();
1083 // Note we expect task 3 to run last because it's non-nestable. 1096 // Note we expect task 3 to run last because it's non-nestable.
1084 EXPECT_THAT(order, testing::ElementsAre(std::string("1"), std::string("2"), 1097 EXPECT_THAT(order, testing::ElementsAre(std::string("1"), std::string("2"),
1085 std::string("4"), std::string("5"), 1098 std::string("4"), std::string("5"),
1086 std::string("3"))); 1099 std::string("3")));
1087 } 1100 }
1088 1101
1102 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriod) {
1103 base::TimeTicks expected_deadline =
1104 clock_->Now() + maximum_idle_period_duration();
1105 base::TimeTicks deadline_in_task;
1106 int run_count = 0;
1107
1108 idle_task_runner_->PostIdleTask(
1109 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
1110
1111 RunUntilIdle();
1112 EXPECT_EQ(0, run_count); // Shouldn't run yet as no idle period.
1113
1114 scheduler_->BeginFrameNotExpectedSoon();
1115 RunUntilIdle();
1116 EXPECT_EQ(1, run_count); // Should have run in a long idle time.
1117 EXPECT_EQ(expected_deadline, deadline_in_task);
1118 }
1119
1120 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodWithPendingDelayedTask) {
1121 base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(30);
1122 base::TimeTicks expected_deadline = clock_->Now() + pending_task_delay;
1123 base::TimeTicks deadline_in_task;
1124 int run_count = 0;
1125
1126 idle_task_runner_->PostIdleTask(
1127 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
1128 default_task_runner_->PostDelayedTask(
1129 FROM_HERE, base::Bind(&NullTask), pending_task_delay);
1130
1131 scheduler_->BeginFrameNotExpectedSoon();
1132 RunUntilIdle();
1133 EXPECT_EQ(1, run_count); // Should have run in a long idle time.
1134 EXPECT_EQ(expected_deadline, deadline_in_task);
1135 }
1136
1137 TEST_F(RendererSchedulerImplTest,
1138 TestLongIdlePeriodWithLatePendingDelayedTask) {
1139 base::TimeDelta pending_task_delay = base::TimeDelta::FromMilliseconds(10);
1140 base::TimeTicks deadline_in_task;
1141 int run_count = 0;
1142
1143 default_task_runner_->PostDelayedTask(
1144 FROM_HERE, base::Bind(&NullTask), pending_task_delay);
1145
1146 // Advance clock until after delayed task was meant to be run.
1147 clock_->AdvanceNow(base::TimeDelta::FromMilliseconds(20));
1148
1149 // Post an idle task and BeginFrameNotExpectedSoon to initiate a long idle
1150 // period. Since there is a late pending delayed task this shouldn't actually
1151 // start an idle period.
1152 idle_task_runner_->PostIdleTask(
1153 FROM_HERE, base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
1154 scheduler_->BeginFrameNotExpectedSoon();
1155 RunUntilIdle();
1156 EXPECT_EQ(0, run_count);
1157
1158 // After the delayed task has been run we should trigger an idle period.
1159 clock_->AdvanceNow(maximum_idle_period_duration());
1160 RunUntilIdle();
1161 EXPECT_EQ(1, run_count);
1162 }
1163
1164 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodRepeating) {
1165 int run_count = 0;
1166
1167 idle_task_runner_->PostIdleTask(
1168 FROM_HERE,
1169 base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
1170
1171 scheduler_->BeginFrameNotExpectedSoon();
1172 RunUntilIdle();
1173 EXPECT_EQ(1, run_count); // Should only run once per idle period.
1174
1175 // Advance time to start of next long idle period and check task reposted task
1176 // gets run.
1177 clock_->AdvanceNow(maximum_idle_period_duration());
1178 RunUntilIdle();
1179 EXPECT_EQ(2, run_count);
1180
1181 // Advance time to start of next long idle period then end idle period with a
1182 // new BeginMainFrame and check idle task doesn't run.
1183 clock_->AdvanceNow(maximum_idle_period_duration());
1184 scheduler_->WillBeginFrame(cc::BeginFrameArgs::Create(
1185 BEGINFRAME_FROM_HERE, clock_->Now(), base::TimeTicks(),
1186 base::TimeDelta::FromMilliseconds(1000), cc::BeginFrameArgs::NORMAL));
1187 RunUntilIdle();
1188 EXPECT_EQ(2, run_count);
1189 }
1190
1191 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodDoesNotWakeScheduler) {
1192 base::TimeTicks deadline_in_task;
1193 int run_count = 0;
1194
1195 // Start a long idle period and get the time it should end.
1196 scheduler_->BeginFrameNotExpectedSoon();
1197 // The scheduler should not run the initiate_next_long_idle_period task if
1198 // there are no idle tasks and no other task woke up the scheduler, thus
1199 // the idle period deadline shouldn't update at the end of the current long
1200 // idle period.
1201 base::TimeTicks idle_period_deadline = CurrentIdleTaskDeadline();
1202 clock_->AdvanceNow(maximum_idle_period_duration());
1203 RunUntilIdle();
1204
1205 base::TimeTicks new_idle_period_deadline = CurrentIdleTaskDeadline();
1206 EXPECT_EQ(idle_period_deadline, new_idle_period_deadline);
1207
1208 // Posting a after-wakeup idle task also shouldn't wake the scheduler or
1209 // initiate the next long idle period.
1210 idle_task_runner_->PostIdleTaskAfterWakeup(
1211 FROM_HERE,
1212 base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
1213 RunUntilIdle();
1214 new_idle_period_deadline = CurrentIdleTaskDeadline();
1215 EXPECT_EQ(idle_period_deadline, new_idle_period_deadline);
1216 EXPECT_EQ(0, run_count);
1217
1218 // Running a normal task should initiate a new long idle period though.
1219 default_task_runner_->PostTask(FROM_HERE, base::Bind(&NullTask));
1220 RunUntilIdle();
1221 new_idle_period_deadline = CurrentIdleTaskDeadline();
1222 EXPECT_EQ(idle_period_deadline + maximum_idle_period_duration(),
1223 new_idle_period_deadline);
1224
1225 EXPECT_EQ(1, run_count);
1226 }
1227
1228 TEST_F(RendererSchedulerImplTest, TestLongIdlePeriodInTouchStartPolicy) {
1229 base::TimeTicks deadline_in_task;
1230 int run_count = 0;
1231
1232 idle_task_runner_->PostIdleTask(
1233 FROM_HERE,
1234 base::Bind(&IdleTestTask, &run_count, &deadline_in_task));
1235
1236 // Observation of touchstart should defer the start of the long idle period.
1237 scheduler_->DidReceiveInputEventOnCompositorThread(
1238 FakeInputEvent(blink::WebInputEvent::TouchStart));
1239 scheduler_->BeginFrameNotExpectedSoon();
1240 RunUntilIdle();
1241 EXPECT_EQ(0, run_count);
1242
1243 // The long idle period should start after the touchstart policy has finished.
1244 clock_->AdvanceNow(priority_escalation_after_input_duration());
1245 RunUntilIdle();
1246 EXPECT_EQ(1, run_count);
1247 }
1248
1089 } // namespace content 1249 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/scheduler/renderer_scheduler_impl.cc ('k') | content/renderer/scheduler/task_queue_manager.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698