1 /*
2 * Copyright 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <ftl/optional.h>
18 #include <gtest/gtest.h>
19
20 #include <common/test/FlagUtils.h>
21 #include <scheduler/Fps.h>
22 #include <scheduler/FrameTargeter.h>
23 #include <scheduler/IVsyncSource.h>
24
25 #include <com_android_graphics_surfaceflinger_flags.h>
26
27 using namespace com::android::graphics::surfaceflinger;
28 using namespace std::chrono_literals;
29
30 namespace android::scheduler {
31 namespace {
32
33 struct VsyncSource final : IVsyncSource {
VsyncSourceandroid::scheduler::__anond20dd1570111::VsyncSource34 VsyncSource(Period period, Period minFramePeriod, TimePoint deadline)
35 : vsyncPeriod(period), framePeriod(minFramePeriod), vsyncDeadline(deadline) {}
36
37 const Period vsyncPeriod;
38 const Period framePeriod;
39 const TimePoint vsyncDeadline;
40
periodandroid::scheduler::__anond20dd1570111::VsyncSource41 Period period() const override { return vsyncPeriod; }
vsyncDeadlineAfterandroid::scheduler::__anond20dd1570111::VsyncSource42 TimePoint vsyncDeadlineAfter(TimePoint, ftl::Optional<TimePoint> = {}) const override {
43 return vsyncDeadline;
44 }
minFramePeriodandroid::scheduler::__anond20dd1570111::VsyncSource45 Period minFramePeriod() const override { return framePeriod; }
46 };
47
48 } // namespace
49
50 class FrameTargeterTestBase : public testing::Test {
51 public:
FrameTargeterTestBase(FeatureFlags flags)52 FrameTargeterTestBase(FeatureFlags flags) : mTargeter(PhysicalDisplayId::fromPort(13), flags) {}
53
target() const54 const auto& target() const { return mTargeter.target(); }
55
wouldPresentEarly(Period vsyncPeriod,Period minFramePeriod) const56 bool wouldPresentEarly(Period vsyncPeriod, Period minFramePeriod) const {
57 return target().wouldPresentEarly(vsyncPeriod, minFramePeriod);
58 }
59
expectedSignaledPresentFence(Period vsyncPeriod,Period minFramePeriod) const60 std::pair<bool /*wouldBackpressure*/, FrameTarget::PresentFence> expectedSignaledPresentFence(
61 Period vsyncPeriod, Period minFramePeriod) const {
62 return target().expectedSignaledPresentFence(vsyncPeriod, minFramePeriod);
63 }
64
65 struct Frame {
Frameandroid::scheduler::FrameTargeterTestBase::Frame66 Frame(FrameTargeterTestBase* testPtr, VsyncId vsyncId, TimePoint& frameBeginTime,
67 Duration frameDuration, Fps refreshRate, Fps peakRefreshRate,
68 FrameTargeter::IsFencePendingFuncPtr isFencePendingFuncPtr = Frame::fenceSignaled,
69 const ftl::Optional<VsyncSource>& vsyncSourceOpt = std::nullopt)
70 : testPtr(testPtr),
71 frameBeginTime(frameBeginTime),
72 period(refreshRate.getPeriod()),
73 minFramePeriod(peakRefreshRate.getPeriod()) {
74 const FrameTargeter::BeginFrameArgs args{.frameBeginTime = frameBeginTime,
75 .vsyncId = vsyncId,
76 .expectedVsyncTime =
77 frameBeginTime + frameDuration,
78 .sfWorkDuration = 10ms,
79 .hwcMinWorkDuration = kHwcMinWorkDuration};
80
81 testPtr->mTargeter.beginFrame(args,
82 vsyncSourceOpt
83 .or_else([&] {
84 return std::make_optional(
85 VsyncSource(period, period,
86 args.expectedVsyncTime));
87 })
88 .value(),
89 isFencePendingFuncPtr);
90 }
91
endandroid::scheduler::FrameTargeterTestBase::Frame92 FenceTimePtr end(CompositionCoverage coverage = CompositionCoverage::Hwc) {
93 if (ended) return nullptr;
94 ended = true;
95
96 auto [fence, fenceTime] = testPtr->mFenceMap.makePendingFenceForTest();
97 testPtr->mTargeter.setPresentFence(std::move(fence), fenceTime);
98
99 testPtr->mTargeter.endFrame({.compositionCoverage = coverage});
100 return fenceTime;
101 }
102
~Frameandroid::scheduler::FrameTargeterTestBase::Frame103 ~Frame() {
104 end();
105 frameBeginTime += period;
106 }
107
fencePendingandroid::scheduler::FrameTargeterTestBase::Frame108 static bool fencePending(const FenceTimePtr&, int) { return true; }
fenceSignaledandroid::scheduler::FrameTargeterTestBase::Frame109 static bool fenceSignaled(const FenceTimePtr&, int) { return false; }
110
111 FrameTargeterTestBase* const testPtr;
112
113 TimePoint& frameBeginTime;
114 const Period period;
115 const Period minFramePeriod;
116
117 bool ended = false;
118 };
119
120 static constexpr Duration kHwcMinWorkDuration = std::chrono::nanoseconds(5ns);
121
122 private:
123 FenceToFenceTimeMap mFenceMap;
124
125 FrameTargeter mTargeter;
126 };
127
128 class FrameTargeterTest : public FrameTargeterTestBase {
129 public:
FrameTargeterTest()130 FrameTargeterTest() : FrameTargeterTestBase(Feature::kBackpressureGpuComposition) {}
131 };
132
133 class FrameTargeterWithExpectedPresentSupportTest : public FrameTargeterTestBase {
134 public:
FrameTargeterWithExpectedPresentSupportTest()135 FrameTargeterWithExpectedPresentSupportTest()
136 : FrameTargeterTestBase(FeatureFlags(Feature::kBackpressureGpuComposition) |
137 Feature::kExpectedPresentTime) {}
138 };
139
TEST_F(FrameTargeterTest,targetsFrames)140 TEST_F(FrameTargeterTest, targetsFrames) {
141 VsyncId vsyncId{42};
142 {
143 TimePoint frameBeginTime(989ms);
144 const Frame frame(this, vsyncId++, frameBeginTime, 10ms, 60_Hz, 60_Hz);
145
146 EXPECT_EQ(target().vsyncId(), VsyncId{42});
147 EXPECT_EQ(target().frameBeginTime(), TimePoint(989ms));
148 EXPECT_EQ(target().expectedPresentTime(), TimePoint(999ms));
149 EXPECT_EQ(target().expectedFrameDuration(), 10ms);
150 }
151 {
152 TimePoint frameBeginTime(1100ms);
153 const Frame frame(this, vsyncId++, frameBeginTime, 11ms, 60_Hz, 60_Hz);
154
155 EXPECT_EQ(target().vsyncId(), VsyncId{43});
156 EXPECT_EQ(target().frameBeginTime(), TimePoint(1100ms));
157 EXPECT_EQ(target().expectedPresentTime(), TimePoint(1111ms));
158 EXPECT_EQ(target().expectedFrameDuration(), 11ms);
159 }
160 }
161
TEST_F(FrameTargeterTest,inflatesExpectedPresentTime)162 TEST_F(FrameTargeterTest, inflatesExpectedPresentTime) {
163 // Negative such that `expectedVsyncTime` is in the past.
164 constexpr Duration kFrameDuration = -3ms;
165 TimePoint frameBeginTime(777ms);
166
167 constexpr Fps kRefreshRate = 120_Hz;
168 const VsyncSource vsyncSource(kRefreshRate.getPeriod(), kRefreshRate.getPeriod(),
169 frameBeginTime + 5ms);
170 const Frame frame(this, VsyncId{123}, frameBeginTime, kFrameDuration, kRefreshRate,
171 kRefreshRate, Frame::fenceSignaled, vsyncSource);
172
173 EXPECT_EQ(target().expectedPresentTime(), vsyncSource.vsyncDeadline + vsyncSource.vsyncPeriod);
174 }
175
TEST_F(FrameTargeterTest,recallsPastVsync)176 TEST_F(FrameTargeterTest, recallsPastVsync) {
177 VsyncId vsyncId{111};
178 TimePoint frameBeginTime(1000ms);
179 constexpr Fps kRefreshRate = 60_Hz;
180 constexpr Period kPeriod = kRefreshRate.getPeriod();
181 constexpr Duration kFrameDuration = 13ms;
182
183 for (int n = 5; n-- > 0;) {
184 FenceTimePtr fence;
185 {
186 Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate,
187 kRefreshRate);
188 fence = frame.end();
189 }
190
191 Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate);
192 const auto [wouldBackpressure, presentFence] =
193 expectedSignaledPresentFence(kPeriod, kPeriod);
194 ASSERT_TRUE(wouldBackpressure);
195 EXPECT_EQ(presentFence.fenceTime, fence);
196 }
197 }
198
TEST_F(FrameTargeterTest,wouldBackpressureAfterTime)199 TEST_F(FrameTargeterTest, wouldBackpressureAfterTime) {
200 SET_FLAG_FOR_TEST(flags::allow_n_vsyncs_in_targeter, true);
201 VsyncId vsyncId{111};
202 TimePoint frameBeginTime(1000ms);
203 constexpr Fps kRefreshRate = 60_Hz;
204 constexpr Period kPeriod = kRefreshRate.getPeriod();
205 constexpr Duration kFrameDuration = 13ms;
206
207 { Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate); }
208 {
209 Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate);
210
211 const auto [wouldBackpressure, presentFence] =
212 expectedSignaledPresentFence(kPeriod, kPeriod);
213 EXPECT_TRUE(wouldBackpressure);
214 }
215 {
216 frameBeginTime += kPeriod;
217 Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate);
218 const auto [wouldBackpressure, presentFence] =
219 expectedSignaledPresentFence(kPeriod, kPeriod);
220 EXPECT_FALSE(wouldBackpressure);
221 }
222 }
223
TEST_F(FrameTargeterTest,wouldBackpressureAfterTimeLegacy)224 TEST_F(FrameTargeterTest, wouldBackpressureAfterTimeLegacy) {
225 SET_FLAG_FOR_TEST(flags::allow_n_vsyncs_in_targeter, false);
226 VsyncId vsyncId{111};
227 TimePoint frameBeginTime(1000ms);
228 constexpr Fps kRefreshRate = 60_Hz;
229 constexpr Period kPeriod = kRefreshRate.getPeriod();
230 constexpr Duration kFrameDuration = 13ms;
231
232 { Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate); }
233 {
234 Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate);
235
236 const auto [wouldBackpressure, presentFence] =
237 expectedSignaledPresentFence(kPeriod, kPeriod);
238 EXPECT_TRUE(wouldBackpressure);
239 }
240 {
241 frameBeginTime += kPeriod;
242 Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate);
243 const auto [wouldBackpressure, presentFence] =
244 expectedSignaledPresentFence(kPeriod, kPeriod);
245 EXPECT_TRUE(wouldBackpressure);
246 }
247 }
248
TEST_F(FrameTargeterTest,recallsPastVsyncTwoVsyncsAhead)249 TEST_F(FrameTargeterTest, recallsPastVsyncTwoVsyncsAhead) {
250 VsyncId vsyncId{222};
251 TimePoint frameBeginTime(2000ms);
252 constexpr Fps kRefreshRate = 120_Hz;
253 constexpr Period kPeriod = kRefreshRate.getPeriod();
254 constexpr Duration kFrameDuration = 10ms;
255
256 FenceTimePtr previousFence = FenceTime::NO_FENCE;
257 FenceTimePtr currentFence = FenceTime::NO_FENCE;
258 for (int n = 5; n-- > 0;) {
259 Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate);
260 EXPECT_EQ(expectedSignaledPresentFence(kPeriod, kPeriod).second.fenceTime, previousFence);
261 previousFence = currentFence;
262 currentFence = frame.end();
263 }
264 }
265
TEST_F(FrameTargeterTest,recallsPastVsyncFiveVsyncsAhead)266 TEST_F(FrameTargeterTest, recallsPastVsyncFiveVsyncsAhead) {
267 SET_FLAG_FOR_TEST(flags::allow_n_vsyncs_in_targeter, true);
268
269 VsyncId vsyncId{222};
270 TimePoint frameBeginTime(2000ms);
271 constexpr Fps kRefreshRate = 120_Hz;
272 constexpr Period kPeriod = kRefreshRate.getPeriod();
273 constexpr Duration kFrameDuration = 40ms;
274
275 FenceTimePtr firstFence = FenceTime::NO_FENCE;
276 for (int n = 5; n-- > 0;) {
277 Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate);
278 const auto fence = frame.end();
279 if (firstFence == FenceTime::NO_FENCE) {
280 firstFence = fence;
281 }
282 }
283
284 Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate);
285 EXPECT_EQ(expectedSignaledPresentFence(kPeriod, kPeriod).second.fenceTime, firstFence);
286 }
287
TEST_F(FrameTargeterTest,recallsPastVsyncTwoVsyncsAheadVrr)288 TEST_F(FrameTargeterTest, recallsPastVsyncTwoVsyncsAheadVrr) {
289 SET_FLAG_FOR_TEST(flags::vrr_config, true);
290
291 VsyncId vsyncId{222};
292 TimePoint frameBeginTime(2000ms);
293 constexpr Fps kRefreshRate = 120_Hz;
294 constexpr Fps kVsyncRate = 240_Hz;
295 constexpr Period kPeriod = kRefreshRate.getPeriod();
296 constexpr Period kVsyncPeriod = kVsyncRate.getPeriod();
297 constexpr Duration kFrameDuration = 10ms;
298
299 FenceTimePtr previousFence = FenceTime::NO_FENCE;
300 FenceTimePtr currentFence = FenceTime::NO_FENCE;
301 for (int n = 5; n-- > 0;) {
302 Frame frame(this, vsyncId++, frameBeginTime, kFrameDuration, kRefreshRate, kRefreshRate);
303 EXPECT_EQ(expectedSignaledPresentFence(kVsyncPeriod, kPeriod).second.fenceTime,
304 previousFence);
305 previousFence = currentFence;
306 currentFence = frame.end();
307 }
308 }
309
TEST_F(FrameTargeterTest,doesNotDetectEarlyPresentIfNoFence)310 TEST_F(FrameTargeterTest, doesNotDetectEarlyPresentIfNoFence) {
311 constexpr Period kPeriod = (60_Hz).getPeriod();
312 EXPECT_EQ(expectedSignaledPresentFence(kPeriod, kPeriod).second.fenceTime, FenceTime::NO_FENCE);
313 EXPECT_FALSE(wouldPresentEarly(kPeriod, kPeriod));
314 }
315
TEST_F(FrameTargeterTest,detectsEarlyPresent)316 TEST_F(FrameTargeterTest, detectsEarlyPresent) {
317 VsyncId vsyncId{333};
318 TimePoint frameBeginTime(3000ms);
319 constexpr Fps kRefreshRate = 60_Hz;
320 constexpr Period kPeriod = kRefreshRate.getPeriod();
321
322 // The target is not early while past present fences are pending.
323 for (int n = 3; n-- > 0;) {
324 {
325 const Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
326 }
327 EXPECT_FALSE(wouldPresentEarly(kPeriod, kPeriod));
328 EXPECT_FALSE(target().earliestPresentTime());
329 }
330
331 // The target is early if the past present fence was signaled.
332 {
333 Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
334 const auto fence = frame.end();
335 fence->signalForTest(frameBeginTime.ns());
336 }
337
338 Frame finalFrame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
339
340 // `finalFrame` would present early, so it has an earliest present time.
341 EXPECT_TRUE(wouldPresentEarly(kPeriod, kPeriod));
342 ASSERT_NE(std::nullopt, target().earliestPresentTime());
343 EXPECT_EQ(*target().earliestPresentTime(),
344 target().expectedPresentTime() - kPeriod - kHwcMinWorkDuration);
345 }
346
TEST_F(FrameTargeterTest,detectsEarlyPresentAfterLongPeriod)347 TEST_F(FrameTargeterTest, detectsEarlyPresentAfterLongPeriod) {
348 VsyncId vsyncId{333};
349 TimePoint frameBeginTime(3000ms);
350 constexpr Fps kRefreshRate = 60_Hz;
351 constexpr Period kPeriod = kRefreshRate.getPeriod();
352
353 // The target is not early while past present fences are pending.
354 for (int n = 3; n-- > 0;) {
355 {
356 const Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
357 }
358 EXPECT_FALSE(wouldPresentEarly(kPeriod, kPeriod));
359 EXPECT_FALSE(target().earliestPresentTime());
360 }
361
362 // The target is early if the past present fence was signaled.
363 {
364 Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
365 const auto fence = frame.end();
366 fence->signalForTest(frameBeginTime.ns());
367 }
368
369 frameBeginTime += 10 * kPeriod;
370
371 Frame finalFrame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
372
373 // `finalFrame` would present early, so it has an earliest present time.
374 EXPECT_TRUE(wouldPresentEarly(kPeriod, kPeriod));
375 ASSERT_NE(std::nullopt, target().earliestPresentTime());
376 EXPECT_EQ(*target().earliestPresentTime(),
377 target().expectedPresentTime() - kPeriod - kHwcMinWorkDuration);
378 }
379
380 // Same as `detectsEarlyPresent`, above, but verifies that we do not set an earliest present time
381 // when there is expected present time support.
TEST_F(FrameTargeterWithExpectedPresentSupportTest,detectsEarlyPresent)382 TEST_F(FrameTargeterWithExpectedPresentSupportTest, detectsEarlyPresent) {
383 VsyncId vsyncId{333};
384 TimePoint frameBeginTime(3000ms);
385 constexpr Fps kRefreshRate = 60_Hz;
386 constexpr Period kPeriod = kRefreshRate.getPeriod();
387
388 // The target is not early while past present fences are pending.
389 for (int n = 3; n-- > 0;) {
390 {
391 const Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
392 }
393 EXPECT_FALSE(wouldPresentEarly(kPeriod, kPeriod));
394 EXPECT_FALSE(target().earliestPresentTime());
395 }
396
397 // The target is early if the past present fence was signaled.
398 {
399 Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
400
401 const auto fence = frame.end();
402 fence->signalForTest(frameBeginTime.ns());
403 }
404
405 Frame finalFrame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
406
407 // `finalFrame` would present early, but we have expected present time support, so it has no
408 // earliest present time.
409 EXPECT_TRUE(wouldPresentEarly(kPeriod, kPeriod));
410 ASSERT_EQ(std::nullopt, target().earliestPresentTime());
411 }
412
TEST_F(FrameTargeterTest,detectsEarlyPresentTwoVsyncsAhead)413 TEST_F(FrameTargeterTest, detectsEarlyPresentTwoVsyncsAhead) {
414 VsyncId vsyncId{444};
415 TimePoint frameBeginTime(4000ms);
416 constexpr Fps kRefreshRate = 120_Hz;
417 constexpr Period kPeriod = kRefreshRate.getPeriod();
418
419 // The target is not early while past present fences are pending.
420 for (int n = 3; n-- > 0;) {
421 {
422 const Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
423 }
424 EXPECT_FALSE(wouldPresentEarly(kPeriod, kPeriod));
425 EXPECT_FALSE(target().earliestPresentTime());
426 }
427 {
428 Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
429
430 const auto fence = frame.end();
431 fence->signalForTest(frameBeginTime.ns());
432 }
433
434 // The target is two VSYNCs ahead, so the past present fence is still pending.
435 EXPECT_FALSE(wouldPresentEarly(kPeriod, kPeriod));
436 EXPECT_FALSE(target().earliestPresentTime());
437
438 { const Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate); }
439
440 Frame finalFrame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
441
442 // The target is early if the past present fence was signaled.
443 EXPECT_TRUE(wouldPresentEarly(kPeriod, kPeriod));
444 ASSERT_NE(std::nullopt, target().earliestPresentTime());
445 EXPECT_EQ(*target().earliestPresentTime(),
446 target().expectedPresentTime() - kPeriod - kHwcMinWorkDuration);
447 }
448
TEST_F(FrameTargeterTest,detectsEarlyPresentThreeVsyncsAhead)449 TEST_F(FrameTargeterTest, detectsEarlyPresentThreeVsyncsAhead) {
450 TimePoint frameBeginTime(5000ms);
451 constexpr Fps kRefreshRate = 144_Hz;
452 constexpr Period kPeriod = kRefreshRate.getPeriod();
453
454 { const Frame frame(this, VsyncId{555}, frameBeginTime, 16ms, kRefreshRate, kRefreshRate); }
455
456 // The target is more than two VSYNCs ahead, but present fences are not tracked that far back.
457 EXPECT_TRUE(wouldPresentEarly(kPeriod, kPeriod));
458 EXPECT_TRUE(target().earliestPresentTime());
459 EXPECT_EQ(*target().earliestPresentTime(),
460 target().expectedPresentTime() - kPeriod - kHwcMinWorkDuration);
461 }
462
TEST_F(FrameTargeterTest,detectsMissedFrames)463 TEST_F(FrameTargeterTest, detectsMissedFrames) {
464 VsyncId vsyncId{555};
465 TimePoint frameBeginTime(5000ms);
466 constexpr Fps kRefreshRate = 60_Hz;
467 constexpr Period kPeriod = kRefreshRate.getPeriod();
468
469 EXPECT_FALSE(target().isFramePending());
470 EXPECT_FALSE(target().didMissFrame());
471 EXPECT_FALSE(target().didMissHwcFrame());
472
473 {
474 const Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
475 EXPECT_FALSE(target().isFramePending());
476
477 // The frame did not miss if the past present fence is invalid.
478 EXPECT_FALSE(target().didMissFrame());
479 EXPECT_FALSE(target().didMissHwcFrame());
480 }
481 {
482 Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate,
483 Frame::fencePending);
484 EXPECT_TRUE(target().isFramePending());
485
486 // The frame missed if the past present fence is pending.
487 EXPECT_TRUE(target().didMissFrame());
488 EXPECT_TRUE(target().didMissHwcFrame());
489
490 frame.end(CompositionCoverage::Gpu);
491 }
492 {
493 const Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate,
494 Frame::fencePending);
495 EXPECT_TRUE(target().isFramePending());
496
497 // The GPU frame missed if the past present fence is pending.
498 EXPECT_TRUE(target().didMissFrame());
499 EXPECT_FALSE(target().didMissHwcFrame());
500 }
501 {
502 Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
503 EXPECT_FALSE(target().isFramePending());
504
505 const auto fence = frame.end();
506 const auto expectedPresentTime = target().expectedPresentTime();
507 fence->signalForTest(expectedPresentTime.ns() + kPeriod.ns() / 2 + 1);
508 }
509 {
510 Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
511 EXPECT_FALSE(target().isFramePending());
512
513 const auto fence = frame.end();
514 const auto expectedPresentTime = target().expectedPresentTime();
515 fence->signalForTest(expectedPresentTime.ns() + kPeriod.ns() / 2);
516
517 // The frame missed if the past present fence was signaled but not within slop.
518 EXPECT_TRUE(target().didMissFrame());
519 EXPECT_TRUE(target().didMissHwcFrame());
520 }
521 {
522 Frame frame(this, vsyncId++, frameBeginTime, 10ms, kRefreshRate, kRefreshRate);
523 EXPECT_FALSE(target().isFramePending());
524
525 // The frame did not miss if the past present fence was signaled within slop.
526 EXPECT_FALSE(target().didMissFrame());
527 EXPECT_FALSE(target().didMissHwcFrame());
528 }
529 }
530
531 } // namespace android::scheduler
532