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

Side by Side Diff: services/gfx/compositor/backend/vsync_scheduler_unittest.cc

Issue 1552963002: Initial checkin of the new Mozart compositor. (Closed) Base URL: git@github.com:domokit/mojo.git@moz-11
Patch Set: fix android build Created 4 years, 10 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
(Empty)
1 // Copyright 2015 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 "services/gfx/compositor/backend/vsync_scheduler.h"
6
7 #include <queue>
8
9 #include "base/bind.h"
10 #include "base/test/test_mock_time_task_runner.h"
11 #include "base/time/tick_clock.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13
14 namespace compositor {
15
16 namespace {
17 constexpr int64_t kVsyncTimebase = -5000;
18 constexpr int64_t kVsyncInterval = 10000;
19 constexpr int64_t kUpdatePhase = -9000;
20 constexpr int64_t kSnapshotPhase = -1000;
21 constexpr int64_t kPresentationPhase = 2000;
22 } // namespace
23
24 class VsyncSchedulerTest : public testing::Test {
25 protected:
26 void SetUp() override { Reset(); }
27
28 void TearDown() override {
29 task_runner_->FastForwardUntilNoTasksRemain();
30 EXPECT_TRUE(expected_callbacks_.empty());
31 }
32
33 void ExpectUpdateCallback(int64_t frame_time,
34 uint64_t frame_interval,
35 int64_t frame_deadline,
36 int64_t presentation_time) {
37 expected_callbacks_.emplace(CallbackType::kUpdate, frame_time, frame_time,
38 frame_interval, frame_deadline,
39 presentation_time);
40 }
41
42 void ExpectSnapshotCallback(int64_t frame_time,
43 uint64_t frame_interval,
44 int64_t frame_deadline,
45 int64_t presentation_time) {
46 expected_callbacks_.emplace(CallbackType::kSnapshot, frame_deadline,
47 frame_time, frame_interval, frame_deadline,
48 presentation_time);
49 }
50
51 MojoTimeTicks GetTimeTicksNow() {
52 return task_runner_->NowTicks().ToInternalValue();
53 }
54
55 void Reset() {
56 task_runner_ = new base::TestMockTimeTaskRunner();
57 SchedulerCallbacks callbacks(
58 base::Bind(&VsyncSchedulerTest::OnUpdate, base::Unretained(this)),
59 base::Bind(&VsyncSchedulerTest::OnSnapshot, base::Unretained(this)));
60 scheduler_.reset(
61 new VsyncScheduler(task_runner_, callbacks,
62 base::Bind(&VsyncSchedulerTest::GetTimeTicksNow,
63 base::Unretained(this))));
64
65 std::queue<ExpectedCallback> victim;
66 expected_callbacks_.swap(victim);
67 }
68
69 void FastForwardTo(int64_t time) {
70 DCHECK(time >= GetTimeTicksNow());
71 task_runner_->FastForwardBy(
72 base::TimeDelta::FromMicroseconds(time - GetTimeTicksNow()));
73 }
74
75 std::unique_ptr<VsyncScheduler> scheduler_;
76
77 private:
78 enum class CallbackType {
79 kUpdate,
80 kSnapshot,
81 };
82
83 struct ExpectedCallback {
84 ExpectedCallback(CallbackType type,
85 int64_t delivery_time,
86 int64_t frame_time,
87 uint64_t frame_interval,
88 int64_t frame_deadline,
89 int64_t presentation_time)
90 : type(type),
91 delivery_time(delivery_time),
92 frame_time(frame_time),
93 frame_interval(frame_interval),
94 frame_deadline(frame_deadline),
95 presentation_time(presentation_time) {}
96
97 CallbackType type;
98 int64_t delivery_time;
99 int64_t frame_time;
100 uint64_t frame_interval;
101 int64_t frame_deadline;
102 int64_t presentation_time;
103 };
104
105 void OnUpdate(const mojo::gfx::composition::FrameInfo& frame_info) {
106 VerifyCallback(CallbackType::kUpdate, frame_info);
107 }
108
109 void OnSnapshot(const mojo::gfx::composition::FrameInfo& frame_info) {
110 VerifyCallback(CallbackType::kSnapshot, frame_info);
111 }
112
113 void VerifyCallback(CallbackType type,
114 const mojo::gfx::composition::FrameInfo& frame_info) {
115 EXPECT_FALSE(expected_callbacks_.empty());
116 if (!expected_callbacks_.empty()) {
117 const ExpectedCallback& c = expected_callbacks_.front();
118 EXPECT_EQ(static_cast<int>(c.type), static_cast<int>(type));
119 EXPECT_EQ(c.delivery_time, GetTimeTicksNow());
120 EXPECT_EQ(c.frame_time, frame_info.frame_time);
121 EXPECT_EQ(c.frame_interval, frame_info.frame_interval);
122 EXPECT_EQ(c.frame_deadline, frame_info.frame_deadline);
123 EXPECT_EQ(c.presentation_time, frame_info.presentation_time);
124 expected_callbacks_.pop();
125 }
126 }
127
128 scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
129 std::queue<ExpectedCallback> expected_callbacks_;
130 };
131
132 TEST_F(VsyncSchedulerTest, StartValidatesArguments) {
133 // Vsync timebase is in the past.
134 EXPECT_TRUE(scheduler_->Start(kVsyncTimebase, kVsyncInterval, kUpdatePhase,
135 kSnapshotPhase, kPresentationPhase));
136 Reset();
137
138 // Vsync timebase is now. (current time == 0)
139 EXPECT_TRUE(scheduler_->Start(0, kVsyncInterval, kUpdatePhase, kSnapshotPhase,
140 kPresentationPhase));
141 Reset();
142
143 // Vsync timebase in the future. (current time == 0)
144 EXPECT_FALSE(scheduler_->Start(1, kVsyncInterval, kUpdatePhase,
145 kSnapshotPhase, kPresentationPhase));
146
147 // Vsync interval too small.
148 EXPECT_FALSE(
149 scheduler_->Start(0, VsyncScheduler::kMinVsyncInterval - 1, 0, 0, 0));
150
151 // Vsync interval at minimum.
152 EXPECT_TRUE(scheduler_->Start(0, VsyncScheduler::kMinVsyncInterval, 0, 0, 0));
153 Reset();
154
155 // Vsync interval at maximum.
156 EXPECT_TRUE(scheduler_->Start(0, VsyncScheduler::kMaxVsyncInterval, 0, 0, 0));
157 Reset();
158
159 // Vsync interval too large.
160 EXPECT_FALSE(
161 scheduler_->Start(0, VsyncScheduler::kMaxVsyncInterval + 1, 0, 0, 0));
162
163 // Snapshot phase earlier than update phase.
164 EXPECT_FALSE(scheduler_->Start(0, kVsyncInterval, kUpdatePhase,
165 kUpdatePhase - 1, kPresentationPhase));
166
167 // Snapshot phase more than one frame behind update phase.
168 EXPECT_FALSE(scheduler_->Start(0, kVsyncInterval, kUpdatePhase,
169 kUpdatePhase + kVsyncInterval + 1,
170 kPresentationPhase));
171
172 // Presentation phase earlier than snapshot phase.
173 EXPECT_FALSE(scheduler_->Start(0, kVsyncInterval, kUpdatePhase,
174 kSnapshotPhase, kSnapshotPhase - 1));
175
176 // Minimum and maximum update vs. snapshot phase delta.
177 EXPECT_TRUE(scheduler_->Start(0, kVsyncInterval, kUpdatePhase, kUpdatePhase,
178 kUpdatePhase));
179 Reset();
180 EXPECT_TRUE(scheduler_->Start(0, kVsyncInterval, kUpdatePhase,
181 kUpdatePhase + kVsyncInterval,
182 kUpdatePhase + kVsyncInterval));
183 Reset();
184 }
185
186 TEST_F(VsyncSchedulerTest, ScheduleRedundantSnapshot) {
187 // Start immediately schedules work.
188 ExpectSnapshotCallback(-4000, kVsyncInterval, 4000, 7000);
189 ExpectUpdateCallback(6000, kVsyncInterval, 14000, 17000);
190 ExpectSnapshotCallback(6000, kVsyncInterval, 14000, 17000);
191 EXPECT_TRUE(scheduler_->Start(kVsyncTimebase, kVsyncInterval, kUpdatePhase,
192 kSnapshotPhase, kPresentationPhase));
193
194 // Shortly after the first update, schedule another snapshot.
195 // Nothing happens because a snapshot is still due at 14000.
196 FastForwardTo(8000);
197 scheduler_->ScheduleFrame(Scheduler::SchedulingMode::kSnapshot);
198 }
199
200 TEST_F(VsyncSchedulerTest, ScheduleRedundantUpdate) {
201 // Start immediately schedules work.
202 ExpectSnapshotCallback(-4000, kVsyncInterval, 4000, 7000);
203 ExpectUpdateCallback(6000, kVsyncInterval, 14000, 17000);
204 ExpectSnapshotCallback(6000, kVsyncInterval, 14000, 17000);
205 EXPECT_TRUE(scheduler_->Start(kVsyncTimebase, kVsyncInterval, kUpdatePhase,
206 kSnapshotPhase, kPresentationPhase));
207
208 // Before the first update, schedule another update.
209 // Nothing happens because an update is still due at 6000.
210 FastForwardTo(5000);
211 scheduler_->ScheduleFrame(Scheduler::SchedulingMode::kUpdateAndSnapshot);
212 }
213
214 TEST_F(VsyncSchedulerTest, ScheduleRequiredSnapshot) {
215 // Start immediately schedules work.
216 ExpectSnapshotCallback(-4000, kVsyncInterval, 4000, 7000);
217 ExpectUpdateCallback(6000, kVsyncInterval, 14000, 17000);
218 ExpectSnapshotCallback(6000, kVsyncInterval, 14000, 17000);
219 EXPECT_TRUE(scheduler_->Start(kVsyncTimebase, kVsyncInterval, kUpdatePhase,
220 kSnapshotPhase, kPresentationPhase));
221
222 // Shortly after the last snapshot, schedule another snapshot.
223 FastForwardTo(15000);
224 ExpectUpdateCallback(16000, kVsyncInterval, 24000, 27000);
225 ExpectSnapshotCallback(16000, kVsyncInterval, 24000, 27000);
226 scheduler_->ScheduleFrame(Scheduler::SchedulingMode::kSnapshot);
227
228 // Exactly at the moment of the next snapshot, schedule another snapshot.
229 FastForwardTo(24000);
230 ExpectUpdateCallback(26000, kVsyncInterval, 34000, 37000);
231 ExpectSnapshotCallback(26000, kVsyncInterval, 34000, 37000);
232 scheduler_->ScheduleFrame(Scheduler::SchedulingMode::kSnapshot);
233
234 // A long time thereafter, with no time to update, schedule another snapshot.
235 FastForwardTo(53000);
236 ExpectSnapshotCallback(46000, kVsyncInterval, 54000, 57000);
237 scheduler_->ScheduleFrame(Scheduler::SchedulingMode::kSnapshot);
238
239 // A long time thereafter, with time to update, schedule another snapshot.
240 FastForwardTo(75000);
241 ExpectUpdateCallback(76000, kVsyncInterval, 84000, 87000);
242 ExpectSnapshotCallback(76000, kVsyncInterval, 84000, 87000);
243 scheduler_->ScheduleFrame(Scheduler::SchedulingMode::kSnapshot);
244 }
245
246 TEST_F(VsyncSchedulerTest, ScheduleRequiredUpdate) {
247 // Start immediately schedules work.
248 ExpectSnapshotCallback(-4000, kVsyncInterval, 4000, 7000);
249 ExpectUpdateCallback(6000, kVsyncInterval, 14000, 17000);
250 ExpectSnapshotCallback(6000, kVsyncInterval, 14000, 17000);
251 EXPECT_TRUE(scheduler_->Start(kVsyncTimebase, kVsyncInterval, kUpdatePhase,
252 kSnapshotPhase, kPresentationPhase));
253
254 // Shortly after the first update, schedule another update.
255 FastForwardTo(8000);
256 ExpectUpdateCallback(16000, kVsyncInterval, 24000, 27000);
257 ExpectSnapshotCallback(16000, kVsyncInterval, 24000, 27000);
258 scheduler_->ScheduleFrame(Scheduler::SchedulingMode::kUpdateAndSnapshot);
259
260 // Exactly at the moment of the next update, schedule another update.
261 FastForwardTo(16000);
262 ExpectUpdateCallback(26000, kVsyncInterval, 34000, 37000);
263 ExpectSnapshotCallback(26000, kVsyncInterval, 34000, 37000);
264 scheduler_->ScheduleFrame(Scheduler::SchedulingMode::kUpdateAndSnapshot);
265
266 // A long time thereafter, with no time to snapshot, schedule another update.
267 FastForwardTo(55000);
268 ExpectUpdateCallback(56000, kVsyncInterval, 64000, 67000);
269 ExpectSnapshotCallback(56000, kVsyncInterval, 64000, 67000);
270 scheduler_->ScheduleFrame(Scheduler::SchedulingMode::kUpdateAndSnapshot);
271
272 // A long time thereafter, with time to snapshot, schedule another update.
273 FastForwardTo(83000);
274 ExpectSnapshotCallback(76000, kVsyncInterval, 84000, 87000);
275 ExpectUpdateCallback(86000, kVsyncInterval, 94000, 97000);
276 ExpectSnapshotCallback(86000, kVsyncInterval, 94000, 97000);
277 scheduler_->ScheduleFrame(Scheduler::SchedulingMode::kUpdateAndSnapshot);
278 }
279
280 TEST_F(VsyncSchedulerTest, StartAndStop) {
281 // Scheduling frames before start does nothing.
282 scheduler_->ScheduleFrame(Scheduler::SchedulingMode::kUpdateAndSnapshot);
283
284 // Starting the scheduler automatically schedules an update.
285 FastForwardTo(15000);
286 ExpectUpdateCallback(16000, kVsyncInterval, 24000, 27000);
287 ExpectSnapshotCallback(16000, kVsyncInterval, 24000, 27000);
288 EXPECT_TRUE(scheduler_->Start(kVsyncTimebase, kVsyncInterval, kUpdatePhase,
289 kSnapshotPhase, kPresentationPhase));
290
291 // Stopping the scheduler suspends further updates.
292 FastForwardTo(24000);
293 scheduler_->Stop();
294 scheduler_->ScheduleFrame(Scheduler::SchedulingMode::kUpdateAndSnapshot);
295
296 // Restarting scheduling resumes updates.
297 FastForwardTo(53000);
298 ExpectSnapshotCallback(46000, kVsyncInterval, 54000, 57000);
299 ExpectUpdateCallback(56000, kVsyncInterval, 64000, 67000);
300 ExpectSnapshotCallback(56000, kVsyncInterval, 64000, 67000);
301 EXPECT_TRUE(scheduler_->Start(kVsyncTimebase, kVsyncInterval, kUpdatePhase,
302 kSnapshotPhase, kPresentationPhase));
303
304 // Stopping the scheduler cancels undelivered updates.
305 FastForwardTo(63000);
306 // canceled: ExpectUpdateCallback(66000, kVsyncInterval, 74000, 77000);
307 // canceled: ExpectSnapshotCallback(66000, kVsyncInterval, 74000, 77000);
308 scheduler_->ScheduleFrame(Scheduler::SchedulingMode::kUpdateAndSnapshot);
309 FastForwardTo(65000);
310 scheduler_->Stop();
311 }
312
313 TEST_F(VsyncSchedulerTest, RedundantStart) {
314 // Start immediately schedules work.
315 ExpectSnapshotCallback(-4000, kVsyncInterval, 4000, 7000);
316 ExpectUpdateCallback(6000, kVsyncInterval, 14000, 17000);
317 ExpectSnapshotCallback(6000, kVsyncInterval, 14000, 17000);
318 EXPECT_TRUE(scheduler_->Start(kVsyncTimebase, kVsyncInterval, kUpdatePhase,
319 kSnapshotPhase, kPresentationPhase));
320
321 // Doing it again has no added effect.
322 EXPECT_TRUE(scheduler_->Start(kVsyncTimebase, kVsyncInterval, kUpdatePhase,
323 kSnapshotPhase, kPresentationPhase));
324
325 // A long time thereafter, schedule another update.
326 FastForwardTo(55000);
327 ExpectUpdateCallback(56000, kVsyncInterval, 64000, 67000);
328 ExpectSnapshotCallback(56000, kVsyncInterval, 64000, 67000);
329 scheduler_->ScheduleFrame(Scheduler::SchedulingMode::kUpdateAndSnapshot);
330 }
331
332 TEST_F(VsyncSchedulerTest, StartWithNewParameters) {
333 // Start immediately schedules work.
334 ExpectSnapshotCallback(-4000, kVsyncInterval, 4000, 7000);
335 ExpectUpdateCallback(6000, kVsyncInterval, 14000, 17000);
336 ExpectSnapshotCallback(6000, kVsyncInterval, 14000, 17000);
337 EXPECT_TRUE(scheduler_->Start(kVsyncTimebase, kVsyncInterval, kUpdatePhase,
338 kSnapshotPhase, kPresentationPhase));
339
340 // After the snapshot is delivered, change parameters.
341 FastForwardTo(14000);
342 ExpectUpdateCallback(17000, kVsyncInterval * 2, 33000, 39000);
343 ExpectSnapshotCallback(17000, kVsyncInterval * 2, 33000, 39000);
344 EXPECT_TRUE(scheduler_->Start(kVsyncTimebase, kVsyncInterval * 2,
345 kUpdatePhase * 2, kSnapshotPhase * 2,
346 kPresentationPhase * 2));
347
348 // Schedule another update with these parameters.
349 FastForwardTo(18000);
350 ExpectUpdateCallback(37000, kVsyncInterval * 2, 53000, 59000);
351 // canceled: ExpectSnapshotCallback(37000, kVsyncInterval * 2, 53000, 59000);
352 scheduler_->ScheduleFrame(Scheduler::SchedulingMode::kUpdateAndSnapshot);
353
354 // At the moment when the update is delivered, change parameters again.
355 // We're too late to cancel the prior update but we do cancel the prior
356 // snapshot and we'll follow it up with another update with the new
357 // parameters.
358 FastForwardTo(37000);
359 ExpectUpdateCallback(46000, kVsyncInterval, 54000, 57000);
360 ExpectSnapshotCallback(46000, kVsyncInterval, 54000, 57000);
361 EXPECT_TRUE(scheduler_->Start(kVsyncTimebase, kVsyncInterval, kUpdatePhase,
362 kSnapshotPhase, kPresentationPhase));
363 }
364
365 // TODO(jeffbrown): Add tests for cases where the compositor has fallen behind.
366
367 } // namespace compositor
OLDNEW
« no previous file with comments | « services/gfx/compositor/backend/vsync_scheduler.cc ('k') | services/gfx/compositor/compositor_app.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698