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

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

Powered by Google App Engine
This is Rietveld 408576698