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

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

Issue 664963002: content: Add RendererScheduler. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix bug in calculating remaining_compositor_priority_time Created 6 years, 1 month 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
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/renderer/scheduler/renderer_scheduler.h"
6
7 #include "base/callback.h"
8 #include "base/test/simple_test_tick_clock.h"
9 #include "base/test/test_simple_task_runner.h"
10 #include "cc/output/begin_frame_args.h"
11 #include "testing/gmock/include/gmock/gmock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace content {
15
16 class DelaySupportingTestSimpleTaskRunner : public base::TestSimpleTaskRunner {
Sami 2014/10/24 10:46:13 I wonder if we could just reuse cc/test/ordered_si
rmcilroy 2014/10/24 14:58:29 I'll look into whether this is possible.
17 public:
18 DelaySupportingTestSimpleTaskRunner(base::SimpleTestTickClock* clock)
19 : clock_(clock) { }
20
21 virtual bool PostDelayedTask(
22 const tracked_objects::Location& from_here,
23 const base::Closure& task,
24 base::TimeDelta delay) override {
25 DCHECK(thread_checker_.CalledOnValidThread());
26 pending_tasks_.push_back(
27 base::TestPendingTask(from_here, task, clock_->NowTicks(), delay,
28 base::TestPendingTask::NESTABLE));
29 return true;
30 }
31
32 virtual bool PostNonNestableDelayedTask(
33 const tracked_objects::Location& from_here,
34 const base::Closure& task,
35 base::TimeDelta delay) override {
36 DCHECK(thread_checker_.CalledOnValidThread());
37 pending_tasks_.push_back(
38 base::TestPendingTask(from_here, task, clock_->NowTicks(), delay,
39 base::TestPendingTask::NON_NESTABLE));
40 return true;
41 }
42
43 void RunPendingTasksIfNotDelayed() {
44 DCHECK(thread_checker_.CalledOnValidThread());
45 // Swap with a local variable to avoid re-entrancy problems.
46 std::deque<base::TestPendingTask> tasks_to_run;
47 tasks_to_run.swap(pending_tasks_);
48 for (std::deque<base::TestPendingTask>::iterator it = tasks_to_run.begin();
49 it != tasks_to_run.end(); ++it) {
50 if (it->GetTimeToRun() <= clock_->NowTicks()) {
51 it->task.Run();
52 } else {
53 pending_tasks_.push_front(*it);
54 }
55 }
56 }
57
58 void RunUntilTasksAreAllDelayed() {
59 DCHECK(thread_checker_.CalledOnValidThread());
60 while (!pending_tasks_.empty() &&
61 pending_tasks_.front().GetTimeToRun() <= clock_->NowTicks()) {
62 RunPendingTasksIfNotDelayed();
63 }
64 }
65
66 protected:
67 virtual ~DelaySupportingTestSimpleTaskRunner() { }
68
69 private:
70 base::SimpleTestTickClock* clock_;
71 };
72
73 class RendererSchedulerForTest : public RendererScheduler {
74 public:
75 RendererSchedulerForTest(
76 scoped_refptr<base::TestSimpleTaskRunner> task_runner,
77 base::SimpleTestTickClock* clock)
78 : RendererScheduler(task_runner),
79 clock_(clock) { }
80 virtual ~RendererSchedulerForTest() { }
81
82 protected:
83 virtual base::TimeTicks Now() const override {
84 return clock_->NowTicks();
85 }
86
87 private:
88 base::SimpleTestTickClock* clock_;
89 };
90
91 class RendererSchedulerTest : public testing::Test {
92 public:
93 RendererSchedulerTest()
94 : clock_(new base::SimpleTestTickClock()),
95 mock_task_runner_(new DelaySupportingTestSimpleTaskRunner(clock_.get())),
96 scheduler_(new RendererSchedulerForTest(mock_task_runner_, clock_.get())),
97 default_task_runner_(scheduler_->DefaultTaskRunner()),
98 compositor_task_runner_(scheduler_->CompositorTaskRunner()),
99 idle_task_runner_(scheduler_->IdleTaskRunner()) { }
100 virtual ~RendererSchedulerTest() { }
101
102 void RunUntilIdle() {
103 mock_task_runner_->RunUntilTasksAreAllDelayed();
104 }
105
106 void EnableIdleTasks() {
107 scheduler_->WillBeginFrame(
108 cc::BeginFrameArgs::Create(clock_->NowTicks(),
109 base::TimeTicks(),
110 base::TimeDelta::FromMilliseconds(1000)));
111 clock_->Advance(base::TimeDelta::FromMilliseconds(800));
112 scheduler_->DidCommitFrameToCompositor();
113 }
114
115 protected:
116 virtual void SetUp() override {
117 // Ensure clock is non-zero.
118 clock_->Advance(base::TimeDelta::FromMilliseconds(5000));
119 }
120
121 scoped_ptr<base::SimpleTestTickClock> clock_;
122 scoped_refptr<DelaySupportingTestSimpleTaskRunner> mock_task_runner_;
123
124 scoped_ptr<RendererScheduler> scheduler_;
125 scoped_refptr<base::SingleThreadTaskRunner> default_task_runner_;
126 scoped_refptr<base::SingleThreadTaskRunner> compositor_task_runner_;
127 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner_;
128
129 DISALLOW_COPY_AND_ASSIGN(RendererSchedulerTest);
130 };
131
132 void OrderedTestTask(int value, int* result) {
133 *result = (*result << 4) | value;
134 }
135
136 void UnorderedTestTask(int value, int* result) {
137 *result += value;
138 }
139
140 void AppendToVectorTestTask(
141 std::vector<std::string>* vector, std::string value) {
142 vector->push_back(value);
143 }
144
145 void AppendToVectorIdleTestTask(
146 std::vector<std::string>* vector,
147 std::string value,
148 base::TimeTicks deadline) {
149 AppendToVectorTestTask(vector, value);
150 }
151
152 void IdleTestTask(
153 bool* task_run,
154 base::TimeTicks expected_deadline,
155 base::TimeTicks deadline) {
156 EXPECT_FALSE(*task_run);
157 EXPECT_EQ(expected_deadline, deadline);
158 *task_run = true;
159 }
160
161 void RepostingIdleTestTask(
162 scoped_refptr<SingleThreadIdleTaskRunner> idle_task_runner,
163 int* run_count,
164 base::TimeTicks deadline) {
165 if (*run_count == 0)
166 idle_task_runner->PostIdleTask(FROM_HERE,
167 base::Bind(&RepostingIdleTestTask, idle_task_runner, run_count));
168 (*run_count)++;
169 }
170
171 TEST_F(RendererSchedulerTest, TestPostDefaultTask) {
172 int result = 0;
173 default_task_runner_->PostTask(FROM_HERE,
174 base::Bind(OrderedTestTask, 1, &result));
175 default_task_runner_->PostTask(FROM_HERE,
176 base::Bind(OrderedTestTask, 2, &result));
177 default_task_runner_->PostTask(FROM_HERE,
178 base::Bind(OrderedTestTask, 3, &result));
179 default_task_runner_->PostTask(FROM_HERE,
180 base::Bind(OrderedTestTask, 4, &result));
181 RunUntilIdle();
182 EXPECT_EQ(0x1234, result);
183 }
184
185 TEST_F(RendererSchedulerTest, TestPostDefaultAndCompositor) {
186 int result = 0;
187 default_task_runner_->PostTask(FROM_HERE,
188 base::Bind(&UnorderedTestTask, 1, &result));
189 compositor_task_runner_->PostTask(FROM_HERE,
190 base::Bind(&UnorderedTestTask, 2, &result));
191 RunUntilIdle();
192 EXPECT_EQ(3, result);
193 }
194
195 TEST_F(RendererSchedulerTest, TestPostIdleTask) {
196 bool task_run = false;
197 base::TimeTicks expected_deadline =
198 clock_->NowTicks() + base::TimeDelta::FromMilliseconds(2300);
199
200 clock_->Advance(base::TimeDelta::FromMilliseconds(100));
201 idle_task_runner_->PostIdleTask(FROM_HERE,
202 base::Bind(&IdleTestTask, &task_run, expected_deadline));
203
204 RunUntilIdle();
205 EXPECT_FALSE(task_run); // Shouldn't run yet as no WillBeginFrame.
206
207 scheduler_->WillBeginFrame(
208 cc::BeginFrameArgs::Create(clock_->NowTicks(),
209 base::TimeTicks(),
210 base::TimeDelta::FromMilliseconds(1000)));
211 RunUntilIdle();
212 EXPECT_FALSE(task_run); // Shouldn't run as no didCommitFrameToCompositor.
213
214 clock_->Advance(base::TimeDelta::FromMilliseconds(1200));
215 scheduler_->DidCommitFrameToCompositor();
216 RunUntilIdle();
217 EXPECT_FALSE(task_run); // We missed the deadline.
218
219 scheduler_->WillBeginFrame(
220 cc::BeginFrameArgs::Create(clock_->NowTicks(),
221 base::TimeTicks(),
222 base::TimeDelta::FromMilliseconds(1000)));
223 clock_->Advance(base::TimeDelta::FromMilliseconds(800));
224 scheduler_->DidCommitFrameToCompositor();
225 RunUntilIdle();
226 EXPECT_TRUE(task_run);
227 }
228
229 TEST_F(RendererSchedulerTest, TestRepostingIdleTask) {
230 int run_count = 0;
231
232 idle_task_runner_->PostIdleTask(FROM_HERE,
233 base::Bind(&RepostingIdleTestTask, idle_task_runner_, &run_count));
234 EnableIdleTasks();
235 RunUntilIdle();
236 EXPECT_EQ(1, run_count);
237
238 // Reposted tasks shouldn't run until next idle period.
239 RunUntilIdle();
240 EXPECT_EQ(1, run_count);
241
242 EnableIdleTasks();
243 RunUntilIdle();
244 EXPECT_EQ(2, run_count);
245 }
246
247 TEST_F(RendererSchedulerTest, TestDefaultPolicy) {
248 std::vector<std::string> order;
249
250 idle_task_runner_->PostIdleTask(FROM_HERE,
251 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("I1")));
252 default_task_runner_->PostTask(FROM_HERE,
253 base::Bind(&AppendToVectorTestTask, &order, std::string("D1")));
254 compositor_task_runner_->PostTask(FROM_HERE,
255 base::Bind(&AppendToVectorTestTask, &order, std::string("C1")));
256 default_task_runner_->PostTask(FROM_HERE,
257 base::Bind(&AppendToVectorTestTask, &order, std::string("D2")));
258 compositor_task_runner_->PostTask(FROM_HERE,
259 base::Bind(&AppendToVectorTestTask, &order, std::string("C2")));
260
261 EnableIdleTasks();
262 RunUntilIdle();
263 EXPECT_THAT(order, testing::ElementsAre(
264 std::string("D1"), std::string("C1"), std::string("D2"),
265 std::string("C2"), std::string("I1")));
266 }
267
268 TEST_F(RendererSchedulerTest, TestCompositorPolicy) {
269 std::vector<std::string> order;
270
271 idle_task_runner_->PostIdleTask(FROM_HERE,
272 base::Bind(&AppendToVectorIdleTestTask, &order, std::string("I1")));
273 default_task_runner_->PostTask(FROM_HERE,
274 base::Bind(&AppendToVectorTestTask, &order, std::string("D1")));
275 compositor_task_runner_->PostTask(FROM_HERE,
276 base::Bind(&AppendToVectorTestTask, &order, std::string("C1")));
277 default_task_runner_->PostTask(FROM_HERE,
278 base::Bind(&AppendToVectorTestTask, &order, std::string("D2")));
279 compositor_task_runner_->PostTask(FROM_HERE,
280 base::Bind(&AppendToVectorTestTask, &order, std::string("C2")));
281
282 scheduler_->DidReceiveInputEvent();
283 EnableIdleTasks();
284 RunUntilIdle();
285 EXPECT_THAT(order, testing::ElementsAre(
286 std::string("C1"), std::string("C2"), std::string("D1"),
287 std::string("D2"), std::string("I1")));
288 }
289
290 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698