1 /*
2 * Copyright 2020 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
18 #include "gmock/gmock-spec-builders.h"
19 #include "mock/MockTimeStats.h"
20 #undef LOG_TAG
21 #define LOG_TAG "LibSurfaceFlingerUnittests"
22
23 #include <FrameTimeline/FrameTimeline.h>
24 #include <gtest/gtest.h>
25 #include <log/log.h>
26 #include <perfetto/trace/trace.pb.h>
27 #include <cinttypes>
28
29 using namespace std::chrono_literals;
30 using testing::_;
31 using testing::AtLeast;
32 using testing::Contains;
33 using FrameTimelineEvent = perfetto::protos::FrameTimelineEvent;
34 using ProtoExpectedDisplayFrameStart =
35 perfetto::protos::FrameTimelineEvent_ExpectedDisplayFrameStart;
36 using ProtoExpectedSurfaceFrameStart =
37 perfetto::protos::FrameTimelineEvent_ExpectedSurfaceFrameStart;
38 using ProtoActualDisplayFrameStart = perfetto::protos::FrameTimelineEvent_ActualDisplayFrameStart;
39 using ProtoActualSurfaceFrameStart = perfetto::protos::FrameTimelineEvent_ActualSurfaceFrameStart;
40 using ProtoFrameEnd = perfetto::protos::FrameTimelineEvent_FrameEnd;
41 using ProtoPresentType = perfetto::protos::FrameTimelineEvent_PresentType;
42 using ProtoJankType = perfetto::protos::FrameTimelineEvent_JankType;
43 using ProtoPredictionType = perfetto::protos::FrameTimelineEvent_PredictionType;
44
45 namespace android::frametimeline {
46
47 static const std::string sLayerNameOne = "layer1";
48 static const std::string sLayerNameTwo = "layer2";
49
50 constexpr const uid_t sUidOne = 0;
51 constexpr pid_t sPidOne = 10;
52 constexpr pid_t sPidTwo = 20;
53 constexpr int32_t sInputEventId = 5;
54 constexpr int32_t sLayerIdOne = 1;
55 constexpr int32_t sLayerIdTwo = 2;
56 constexpr GameMode sGameMode = GameMode::Unsupported;
57
58 class FrameTimelineTest : public testing::Test {
59 public:
FrameTimelineTest()60 FrameTimelineTest() {
61 const ::testing::TestInfo* const test_info =
62 ::testing::UnitTest::GetInstance()->current_test_info();
63 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
64 }
65
~FrameTimelineTest()66 ~FrameTimelineTest() {
67 const ::testing::TestInfo* const test_info =
68 ::testing::UnitTest::GetInstance()->current_test_info();
69 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
70 }
71
SetUpTestSuite()72 static void SetUpTestSuite() {
73 // Need to initialize tracing in process for testing, and only once per test suite.
74 perfetto::TracingInitArgs args;
75 args.backends = perfetto::kInProcessBackend;
76 perfetto::Tracing::Initialize(args);
77 }
78
SetUp()79 void SetUp() override {
80 constexpr bool kUseBootTimeClock = true;
81 mTimeStats = std::make_shared<mock::TimeStats>();
82 mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats, kSurfaceFlingerPid,
83 kTestThresholds, !kUseBootTimeClock);
84 mFrameTimeline->registerDataSource();
85 mTokenManager = &mFrameTimeline->mTokenManager;
86 mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
87 maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
88 maxTokens = mTokenManager->kMaxTokens;
89 }
90
91 // Each tracing session can be used for a single block of Start -> Stop.
getTracingSessionForTest()92 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
93 perfetto::TraceConfig cfg;
94 cfg.set_duration_ms(500);
95 cfg.add_buffers()->set_size_kb(1024);
96 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
97 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
98
99 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
100 tracingSession->Setup(cfg);
101 return tracingSession;
102 }
103
readFrameTimelinePacketsBlocking(perfetto::TracingSession * tracingSession)104 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
105 perfetto::TracingSession* tracingSession) {
106 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
107 perfetto::protos::Trace trace;
108 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
109
110 std::vector<perfetto::protos::TracePacket> packets;
111 for (const auto& packet : trace.packet()) {
112 if (!packet.has_frame_timeline_event()) {
113 continue;
114 }
115 packets.emplace_back(packet);
116 }
117 return packets;
118 }
119
addEmptySurfaceFrame()120 void addEmptySurfaceFrame() {
121 auto surfaceFrame =
122 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
123 sLayerNameOne, sLayerNameOne,
124 /*isBuffer*/ false, sGameMode);
125 mFrameTimeline->addSurfaceFrame(std::move(surfaceFrame));
126 }
127
addEmptyDisplayFrame()128 void addEmptyDisplayFrame() {
129 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
130 // Trigger a flushPresentFence by calling setSfPresent for the next frame
131 mFrameTimeline->setSfPresent(2500, presentFence1);
132 }
133
flushTokens()134 void flushTokens() {
135 for (size_t i = 0; i < maxTokens; i++) {
136 mTokenManager->generateTokenForPredictions({});
137 }
138 EXPECT_EQ(getPredictions().size(), maxTokens);
139 }
140
getSurfaceFrame(size_t displayFrameIdx,size_t surfaceFrameIdx)141 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
142 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
143 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
144 ->getSurfaceFrames()[surfaceFrameIdx]);
145 }
146
getDisplayFrame(size_t idx)147 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
148 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
149 return mFrameTimeline->mDisplayFrames[idx];
150 }
151
compareTimelineItems(const TimelineItem & a,const TimelineItem & b)152 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
153 return a.startTime == b.startTime && a.endTime == b.endTime &&
154 a.presentTime == b.presentTime;
155 }
156
getPredictions() const157 const std::map<int64_t, TimelineItem>& getPredictions() const {
158 return mTokenManager->mPredictions;
159 }
160
getNumberOfDisplayFrames() const161 uint32_t getNumberOfDisplayFrames() const {
162 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
163 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
164 }
165
snoopCurrentTraceCookie() const166 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
167
flushTrace()168 void flushTrace() {
169 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
170 FrameTimelineDataSource::Trace(
171 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
172 }
173
174 std::shared_ptr<mock::TimeStats> mTimeStats;
175 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
176 impl::TokenManager* mTokenManager;
177 TraceCookieCounter* mTraceCookieCounter;
178 FenceToFenceTimeMap fenceFactory;
179 uint32_t* maxDisplayFrames;
180 size_t maxTokens;
181 static constexpr pid_t kSurfaceFlingerPid = 666;
182 static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count();
183 static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(0ns).count();
184 static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count();
185 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
186 kDeadlineThreshold,
187 kStartThreshold};
188 };
189
TEST_F(FrameTimelineTest,tokenManagerRemovesStalePredictions)190 TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
191 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
192 EXPECT_EQ(getPredictions().size(), 1u);
193 flushTokens();
194 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
195 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
196
197 // token1 should have expired
198 EXPECT_EQ(predictions.has_value(), false);
199
200 predictions = mTokenManager->getPredictionsForToken(token2);
201 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
202 }
203
TEST_F(FrameTimelineTest,createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid)204 TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
205 auto surfaceFrame1 =
206 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
207 sLayerNameOne, sLayerNameOne,
208 /*isBuffer*/ true, sGameMode);
209 auto surfaceFrame2 =
210 mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerIdOne,
211 sLayerNameOne, sLayerNameOne,
212 /*isBuffer*/ true, sGameMode);
213 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
214 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
215 }
216
TEST_F(FrameTimelineTest,createSurfaceFrameForToken_noToken)217 TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
218 auto surfaceFrame =
219 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
220 sLayerNameOne, sLayerNameOne,
221 /*isBuffer*/ true, sGameMode);
222 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
223 }
224
TEST_F(FrameTimelineTest,createSurfaceFrameForToken_expiredToken)225 TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
226 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
227 flushTokens();
228 FrameTimelineInfo ftInfo;
229 ftInfo.vsyncId = token1;
230 ftInfo.inputEventId = sInputEventId;
231 auto surfaceFrame =
232 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
233 sLayerNameOne, sLayerNameOne,
234 /*isBuffer*/ true, sGameMode);
235
236 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
237 }
238
TEST_F(FrameTimelineTest,createSurfaceFrameForToken_validToken)239 TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
240 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
241 FrameTimelineInfo ftInfo;
242 ftInfo.vsyncId = token1;
243 ftInfo.inputEventId = sInputEventId;
244 auto surfaceFrame =
245 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
246 sLayerNameOne, sLayerNameOne,
247 /*isBuffer*/ true, sGameMode);
248
249 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
250 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
251 }
252
TEST_F(FrameTimelineTest,createSurfaceFrameForToken_validInputEventId)253 TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
254 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
255 constexpr int32_t inputEventId = 1;
256 FrameTimelineInfo ftInfo;
257 ftInfo.vsyncId = token1;
258 ftInfo.inputEventId = inputEventId;
259 auto surfaceFrame =
260 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
261 sLayerNameOne, sLayerNameOne,
262 /*isBuffer*/ true, sGameMode);
263
264 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
265 }
266
TEST_F(FrameTimelineTest,presentFenceSignaled_droppedFramesNotUpdated)267 TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
268 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
269 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
270 FrameTimelineInfo ftInfo;
271 ftInfo.vsyncId = token1;
272 ftInfo.inputEventId = sInputEventId;
273 auto surfaceFrame1 =
274 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
275 sLayerNameOne, sLayerNameOne,
276 /*isBuffer*/ true, sGameMode);
277
278 // Set up the display frame
279 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
280 surfaceFrame1->setDropTime(12);
281 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
282 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
283 mFrameTimeline->setSfPresent(25, presentFence1);
284 presentFence1->signalForTest(30);
285
286 addEmptyDisplayFrame();
287
288 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
289 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
290 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
291 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
292 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
293 }
294
TEST_F(FrameTimelineTest,presentFenceSignaled_presentedFramesUpdated)295 TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
296 // Layer specific increment
297 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
298 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
299 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
300 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
301 FrameTimelineInfo ftInfo;
302 ftInfo.vsyncId = surfaceFrameToken1;
303 ftInfo.inputEventId = sInputEventId;
304 auto surfaceFrame1 =
305 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
306 sLayerNameOne, sLayerNameOne,
307 /*isBuffer*/ true, sGameMode);
308 auto surfaceFrame2 =
309 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdTwo,
310 sLayerNameTwo, sLayerNameTwo,
311 /*isBuffer*/ true, sGameMode);
312 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
313 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
314 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
315 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
316 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
317 mFrameTimeline->setSfPresent(26, presentFence1);
318 auto displayFrame = getDisplayFrame(0);
319 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
320 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
321 presentFence1->signalForTest(42);
322
323 // Fences haven't been flushed yet, so it should be 0
324 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
325 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
326 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
327
328 addEmptyDisplayFrame();
329
330 // Fences have flushed, so the present timestamps should be updated
331 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
332 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
333 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
334 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
335 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
336 }
337
TEST_F(FrameTimelineTest,displayFramesSlidingWindowMovesAfterLimit)338 TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
339 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
340 int frameTimeFactor = 0;
341 // Layer specific increment
342 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
343 .Times(static_cast<int32_t>(*maxDisplayFrames));
344 for (size_t i = 0; i < *maxDisplayFrames; i++) {
345 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
346 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
347 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
348 int64_t sfToken = mTokenManager->generateTokenForPredictions(
349 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
350 FrameTimelineInfo ftInfo;
351 ftInfo.vsyncId = surfaceFrameToken;
352 ftInfo.inputEventId = sInputEventId;
353 auto surfaceFrame =
354 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
355 sLayerNameOne, sLayerNameOne,
356 /*isBuffer*/ true, sGameMode);
357 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
358 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
359 mFrameTimeline->addSurfaceFrame(surfaceFrame);
360 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
361 presentFence->signalForTest(32 + frameTimeFactor);
362 frameTimeFactor += 30;
363 }
364 auto displayFrame0 = getDisplayFrame(0);
365
366 // The 0th Display Frame should have actuals 22, 27, 32
367 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
368
369 // Add one more display frame
370 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
371 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
372 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
373 int64_t sfToken = mTokenManager->generateTokenForPredictions(
374 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
375 FrameTimelineInfo ftInfo;
376 ftInfo.vsyncId = surfaceFrameToken;
377 ftInfo.inputEventId = sInputEventId;
378 auto surfaceFrame =
379 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
380 sLayerNameOne, sLayerNameOne,
381 /*isBuffer*/ true, sGameMode);
382 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
383 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
384 mFrameTimeline->addSurfaceFrame(surfaceFrame);
385 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
386 presentFence->signalForTest(32 + frameTimeFactor);
387 displayFrame0 = getDisplayFrame(0);
388
389 // The window should have slided by 1 now and the previous 0th display frame
390 // should have been removed from the deque
391 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
392 }
393
TEST_F(FrameTimelineTest,surfaceFrameEndTimeAcquireFenceAfterQueue)394 TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
395 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
396 "acquireFenceAfterQueue",
397 "acquireFenceAfterQueue",
398 /*isBuffer*/ true, sGameMode);
399 surfaceFrame->setActualQueueTime(123);
400 surfaceFrame->setAcquireFenceTime(456);
401 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
402 }
403
TEST_F(FrameTimelineTest,surfaceFrameEndTimeAcquireFenceBeforeQueue)404 TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
405 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
406 "acquireFenceAfterQueue",
407 "acquireFenceAfterQueue",
408 /*isBuffer*/ true, sGameMode);
409 surfaceFrame->setActualQueueTime(456);
410 surfaceFrame->setAcquireFenceTime(123);
411 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
412 }
413
TEST_F(FrameTimelineTest,setMaxDisplayFramesSetsSizeProperly)414 TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
415 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
416 presentFence->signalForTest(2);
417
418 // Size shouldn't exceed maxDisplayFrames - 64
419 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
420 auto surfaceFrame =
421 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
422 sLayerNameOne, sLayerNameOne,
423 /*isBuffer*/ true, sGameMode);
424 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
425 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
426 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
427 mFrameTimeline->addSurfaceFrame(surfaceFrame);
428 mFrameTimeline->setSfPresent(27, presentFence);
429 }
430 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
431
432 // Increase the size to 256
433 mFrameTimeline->setMaxDisplayFrames(256);
434 EXPECT_EQ(*maxDisplayFrames, 256u);
435
436 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
437 auto surfaceFrame =
438 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
439 sLayerNameOne, sLayerNameOne,
440 /*isBuffer*/ true, sGameMode);
441 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
442 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
443 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
444 mFrameTimeline->addSurfaceFrame(surfaceFrame);
445 mFrameTimeline->setSfPresent(27, presentFence);
446 }
447 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
448
449 // Shrink the size to 128
450 mFrameTimeline->setMaxDisplayFrames(128);
451 EXPECT_EQ(*maxDisplayFrames, 128u);
452
453 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
454 auto surfaceFrame =
455 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
456 sLayerNameOne, sLayerNameOne,
457 /*isBuffer*/ true, sGameMode);
458 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
459 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
460 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
461 mFrameTimeline->addSurfaceFrame(surfaceFrame);
462 mFrameTimeline->setSfPresent(27, presentFence);
463 }
464 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
465 }
466
TEST_F(FrameTimelineTest,presentFenceSignaled_invalidSignalTime)467 TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
468 Fps refreshRate = Fps::fromPeriodNsecs(11);
469
470 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
471 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
472 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
473 FrameTimelineInfo ftInfo;
474 ftInfo.vsyncId = surfaceFrameToken1;
475 ftInfo.inputEventId = sInputEventId;
476
477 auto surfaceFrame1 =
478 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
479 sLayerNameOne, sLayerNameOne,
480 /*isBuffer*/ true, sGameMode);
481 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
482 surfaceFrame1->setAcquireFenceTime(20);
483 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
484 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
485
486 mFrameTimeline->setSfPresent(59, presentFence1);
487 presentFence1->signalForTest(-1);
488 addEmptyDisplayFrame();
489
490 auto displayFrame0 = getDisplayFrame(0);
491 EXPECT_EQ(displayFrame0->getActuals().presentTime, 59);
492 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown | JankType::DisplayHAL);
493 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
494 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
495 }
496
497 // Tests related to TimeStats
TEST_F(FrameTimelineTest,presentFenceSignaled_doesNotReportForInvalidTokens)498 TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
499 Fps refreshRate = Fps::fromPeriodNsecs(11);
500 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
501 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
502 int64_t surfaceFrameToken1 = -1;
503 int64_t sfToken1 = -1;
504 FrameTimelineInfo ftInfo;
505 ftInfo.vsyncId = surfaceFrameToken1;
506 ftInfo.inputEventId = sInputEventId;
507
508 auto surfaceFrame1 =
509 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
510 sLayerNameOne, sLayerNameOne,
511 /*isBuffer*/ true, sGameMode);
512 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
513 surfaceFrame1->setAcquireFenceTime(20);
514 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
515 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
516 presentFence1->signalForTest(70);
517
518 mFrameTimeline->setSfPresent(59, presentFence1);
519 }
520
TEST_F(FrameTimelineTest,presentFenceSignaled_reportsLongSfCpu)521 TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
522 Fps refreshRate = Fps::fromPeriodNsecs(11);
523 EXPECT_CALL(*mTimeStats,
524 incrementJankyFrames(
525 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
526 sLayerNameOne, sGameMode,
527 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
528 0}));
529 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
530 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
531 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
532 FrameTimelineInfo ftInfo;
533 ftInfo.vsyncId = surfaceFrameToken1;
534 ftInfo.inputEventId = sInputEventId;
535
536 auto surfaceFrame1 =
537 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
538 sLayerNameOne, sLayerNameOne,
539 /*isBuffer*/ true, sGameMode);
540 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
541 surfaceFrame1->setAcquireFenceTime(20);
542 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
543 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
544 presentFence1->signalForTest(70);
545
546 mFrameTimeline->setSfPresent(62, presentFence1);
547 }
548
TEST_F(FrameTimelineTest,presentFenceSignaled_reportsLongSfGpu)549 TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfGpu) {
550 Fps refreshRate = Fps::fromPeriodNsecs(11);
551 EXPECT_CALL(*mTimeStats,
552 incrementJankyFrames(
553 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
554 sLayerNameOne, sGameMode,
555 JankType::SurfaceFlingerGpuDeadlineMissed, 4, 10,
556 0}));
557 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
558 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
559 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
560 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
561 FrameTimelineInfo ftInfo;
562 ftInfo.vsyncId = surfaceFrameToken1;
563 ftInfo.inputEventId = sInputEventId;
564
565 auto surfaceFrame1 =
566 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
567 sLayerNameOne, sLayerNameOne,
568 /*isBuffer*/ true, sGameMode);
569 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
570 surfaceFrame1->setAcquireFenceTime(20);
571 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
572 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
573 gpuFence1->signalForTest(64);
574 presentFence1->signalForTest(70);
575
576 mFrameTimeline->setSfPresent(59, presentFence1, gpuFence1);
577 }
578
TEST_F(FrameTimelineTest,presentFenceSignaled_reportsDisplayMiss)579 TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
580 Fps refreshRate = Fps::fromPeriodNsecs(30);
581 EXPECT_CALL(*mTimeStats,
582 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
583 sLayerNameOne, sGameMode,
584 JankType::DisplayHAL, -4, 0, 0}));
585
586 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
587 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
588 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
589 FrameTimelineInfo ftInfo;
590 ftInfo.vsyncId = surfaceFrameToken1;
591 ftInfo.inputEventId = sInputEventId;
592
593 auto surfaceFrame1 =
594 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
595 sLayerNameOne, sLayerNameOne,
596 /*isBuffer*/ true, sGameMode);
597 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
598 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
599 surfaceFrame1->setAcquireFenceTime(20);
600 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
601 presentFence1->signalForTest(90);
602 mFrameTimeline->setSfPresent(56, presentFence1);
603 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
604 }
605
TEST_F(FrameTimelineTest,presentFenceSignaled_reportsAppMiss)606 TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
607 Fps refreshRate = 11_Hz;
608 EXPECT_CALL(*mTimeStats,
609 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
610 sLayerNameOne, sGameMode,
611 JankType::AppDeadlineMissed, -4, 0,
612 25}));
613 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
614 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
615 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
616 FrameTimelineInfo ftInfo;
617 ftInfo.vsyncId = surfaceFrameToken1;
618 ftInfo.inputEventId = sInputEventId;
619
620 auto surfaceFrame1 =
621 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
622 sLayerNameOne, sLayerNameOne,
623 /*isBuffer*/ true, sGameMode);
624 surfaceFrame1->setAcquireFenceTime(45);
625 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
626
627 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
628 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
629 presentFence1->signalForTest(90);
630 mFrameTimeline->setSfPresent(86, presentFence1);
631
632 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
633 }
634
TEST_F(FrameTimelineTest,presentFenceSignaled_reportsSfScheduling)635 TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
636 Fps refreshRate = Fps::fromPeriodNsecs(32);
637 EXPECT_CALL(*mTimeStats,
638 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
639 sLayerNameOne, sGameMode,
640 JankType::SurfaceFlingerScheduling,
641 -4, 0, -10}));
642 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
643 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
644 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
645 FrameTimelineInfo ftInfo;
646 ftInfo.vsyncId = surfaceFrameToken1;
647 ftInfo.inputEventId = sInputEventId;
648
649 auto surfaceFrame1 =
650 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
651 sLayerNameOne, sLayerNameOne,
652 /*isBuffer*/ true, sGameMode);
653 surfaceFrame1->setAcquireFenceTime(50);
654 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
655
656 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
657 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
658 presentFence1->signalForTest(60);
659 mFrameTimeline->setSfPresent(56, presentFence1);
660
661 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
662 }
663
TEST_F(FrameTimelineTest,presentFenceSignaled_reportsSfPredictionError)664 TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
665 Fps refreshRate = Fps::fromPeriodNsecs(16);
666 EXPECT_CALL(*mTimeStats,
667 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
668 sLayerNameOne, sGameMode,
669 JankType::PredictionError, -4, 5,
670 0}));
671 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
672 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
673 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
674 FrameTimelineInfo ftInfo;
675 ftInfo.vsyncId = surfaceFrameToken1;
676 ftInfo.inputEventId = sInputEventId;
677
678 auto surfaceFrame1 =
679 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
680 sLayerNameOne, sLayerNameOne,
681 /*isBuffer*/ true, sGameMode);
682 surfaceFrame1->setAcquireFenceTime(40);
683 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
684
685 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
686 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
687 presentFence1->signalForTest(65);
688 mFrameTimeline->setSfPresent(56, presentFence1);
689
690 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
691 }
692
TEST_F(FrameTimelineTest,presentFenceSignaled_reportsAppBufferStuffing)693 TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
694 Fps refreshRate = Fps::fromPeriodNsecs(32);
695 EXPECT_CALL(*mTimeStats,
696 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
697 sLayerNameOne, sGameMode,
698 JankType::BufferStuffing, -4, 0,
699 0}));
700 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
701 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
702 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
703 FrameTimelineInfo ftInfo;
704 ftInfo.vsyncId = surfaceFrameToken1;
705 ftInfo.inputEventId = sInputEventId;
706
707 auto surfaceFrame1 =
708 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
709 sLayerNameOne, sLayerNameOne,
710 /*isBuffer*/ true, sGameMode);
711 surfaceFrame1->setAcquireFenceTime(40);
712 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate);
713
714 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
715 /*previousLatchTime*/ 56);
716 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
717 presentFence1->signalForTest(90);
718 mFrameTimeline->setSfPresent(86, presentFence1);
719
720 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
721 }
722
TEST_F(FrameTimelineTest,presentFenceSignaled_reportsAppMissWithRenderRate)723 TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
724 Fps refreshRate = Fps::fromPeriodNsecs(11);
725 Fps renderRate = Fps::fromPeriodNsecs(30);
726 EXPECT_CALL(*mTimeStats,
727 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne,
728 sLayerNameOne, sGameMode,
729 JankType::AppDeadlineMissed, -4, 0,
730 25}));
731 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
732 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
733 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
734 FrameTimelineInfo ftInfo;
735 ftInfo.vsyncId = surfaceFrameToken1;
736 ftInfo.inputEventId = sInputEventId;
737
738 auto surfaceFrame1 =
739 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
740 sLayerNameOne, sLayerNameOne,
741 /*isBuffer*/ true, sGameMode);
742 surfaceFrame1->setAcquireFenceTime(45);
743 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
744
745 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
746 surfaceFrame1->setRenderRate(renderRate);
747 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
748 presentFence1->signalForTest(90);
749 mFrameTimeline->setSfPresent(86, presentFence1);
750
751 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
752 }
753
TEST_F(FrameTimelineTest,presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame)754 TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
755 Fps refreshRate = Fps::fromPeriodNsecs(11);
756 Fps renderRate = Fps::fromPeriodNsecs(30);
757
758 EXPECT_CALL(*mTimeStats,
759 incrementJankyFrames(
760 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
761 sGameMode,
762 JankType::Unknown | JankType::AppDeadlineMissed,
763 0, 0, 25}));
764 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
765 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
766 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
767 FrameTimelineInfo ftInfo;
768 ftInfo.vsyncId = surfaceFrameToken1;
769 ftInfo.inputEventId = sInputEventId;
770
771 auto surfaceFrame1 =
772 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
773 sLayerNameOne, sLayerNameOne,
774 /*isBuffer*/ true, sGameMode);
775 surfaceFrame1->setAcquireFenceTime(45);
776 // Trigger a prediction expiry
777 flushTokens();
778 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
779
780 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
781 surfaceFrame1->setRenderRate(renderRate);
782 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
783 presentFence1->signalForTest(90);
784 mFrameTimeline->setSfPresent(86, presentFence1);
785
786 auto displayFrame = getDisplayFrame(0);
787 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
788 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
789 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
790 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
791
792 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
793 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
794 }
795
796 /*
797 * Tracing Tests
798 *
799 * Trace packets are flushed all the way only when the next packet is traced.
800 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
801 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
802 * will have additional empty frames created for this reason.
803 */
TEST_F(FrameTimelineTest,tracing_noPacketsSentWithoutTraceStart)804 TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
805 auto tracingSession = getTracingSessionForTest();
806 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
807 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
808 FrameTimelineInfo ftInfo;
809 ftInfo.vsyncId = token1;
810 ftInfo.inputEventId = sInputEventId;
811 auto surfaceFrame1 =
812 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
813 sLayerNameOne, sLayerNameOne,
814 /*isBuffer*/ true, sGameMode);
815
816 // Set up the display frame
817 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
818 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
819 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
820 mFrameTimeline->setSfPresent(25, presentFence1);
821 presentFence1->signalForTest(30);
822
823 addEmptyDisplayFrame();
824
825 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
826 EXPECT_EQ(packets.size(), 0u);
827 }
828
TEST_F(FrameTimelineTest,tracing_sanityTest)829 TEST_F(FrameTimelineTest, tracing_sanityTest) {
830 auto tracingSession = getTracingSessionForTest();
831 // Layer specific increment
832 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
833 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
834
835 tracingSession->StartBlocking();
836 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
837 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
838 FrameTimelineInfo ftInfo;
839 ftInfo.vsyncId = token1;
840 ftInfo.inputEventId = sInputEventId;
841 auto surfaceFrame1 =
842 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
843 sLayerNameOne, sLayerNameOne,
844 /*isBuffer*/ true, sGameMode);
845
846 // Set up the display frame
847 mFrameTimeline->setSfWakeUp(token2, 20, Fps::fromPeriodNsecs(11));
848 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
849 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
850 mFrameTimeline->setSfPresent(25, presentFence1);
851 presentFence1->signalForTest(30);
852
853 addEmptyDisplayFrame();
854 flushTrace();
855 tracingSession->StopBlocking();
856
857 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
858 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
859 EXPECT_EQ(packets.size(), 8u);
860 }
861
TEST_F(FrameTimelineTest,traceDisplayFrame_invalidTokenDoesNotEmitTracePacket)862 TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
863 auto tracingSession = getTracingSessionForTest();
864 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
865
866 tracingSession->StartBlocking();
867
868 // Set up the display frame
869 mFrameTimeline->setSfWakeUp(-1, 20, Fps::fromPeriodNsecs(11));
870 mFrameTimeline->setSfPresent(25, presentFence1);
871 presentFence1->signalForTest(30);
872
873 addEmptyDisplayFrame();
874 flushTrace();
875 tracingSession->StopBlocking();
876
877 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
878 EXPECT_EQ(packets.size(), 0u);
879 }
880
TEST_F(FrameTimelineTest,traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket)881 TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
882 auto tracingSession = getTracingSessionForTest();
883 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
884
885 tracingSession->StartBlocking();
886 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
887 auto surfaceFrame1 =
888 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
889 sLayerNameOne, sLayerNameOne,
890 /*isBuffer*/ true, sGameMode);
891
892 // Set up the display frame
893 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
894 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
895 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
896 mFrameTimeline->setSfPresent(25, presentFence1);
897 presentFence1->signalForTest(30);
898
899 addEmptyDisplayFrame();
900 flushTrace();
901 tracingSession->StopBlocking();
902
903 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
904 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
905 // token).
906 EXPECT_EQ(packets.size(), 4u);
907 }
908
createProtoExpectedDisplayFrameStart(int64_t cookie,int64_t token,pid_t pid)909 ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
910 pid_t pid) {
911 ProtoExpectedDisplayFrameStart proto;
912 proto.set_cookie(cookie);
913 proto.set_token(token);
914 proto.set_pid(pid);
915 return proto;
916 }
917
createProtoActualDisplayFrameStart(int64_t cookie,int64_t token,pid_t pid,ProtoPresentType presentType,bool onTimeFinish,bool gpuComposition,ProtoJankType jankType,ProtoPredictionType predictionType)918 ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
919 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
920 bool gpuComposition, ProtoJankType jankType, ProtoPredictionType predictionType) {
921 ProtoActualDisplayFrameStart proto;
922 proto.set_cookie(cookie);
923 proto.set_token(token);
924 proto.set_pid(pid);
925 proto.set_present_type(presentType);
926 proto.set_on_time_finish(onTimeFinish);
927 proto.set_gpu_composition(gpuComposition);
928 proto.set_jank_type(jankType);
929 proto.set_prediction_type(predictionType);
930 return proto;
931 }
932
createProtoExpectedSurfaceFrameStart(int64_t cookie,int64_t token,int64_t displayFrameToken,pid_t pid,std::string layerName)933 ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
934 int64_t displayFrameToken,
935 pid_t pid,
936 std::string layerName) {
937 ProtoExpectedSurfaceFrameStart proto;
938 proto.set_cookie(cookie);
939 proto.set_token(token);
940 proto.set_display_frame_token(displayFrameToken);
941 proto.set_pid(pid);
942 proto.set_layer_name(layerName);
943 return proto;
944 }
945
createProtoActualSurfaceFrameStart(int64_t cookie,int64_t token,int64_t displayFrameToken,pid_t pid,std::string layerName,ProtoPresentType presentType,bool onTimeFinish,bool gpuComposition,ProtoJankType jankType,ProtoPredictionType predictionType,bool isBuffer)946 ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
947 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
948 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
949 ProtoJankType jankType, ProtoPredictionType predictionType, bool isBuffer) {
950 ProtoActualSurfaceFrameStart proto;
951 proto.set_cookie(cookie);
952 proto.set_token(token);
953 proto.set_display_frame_token(displayFrameToken);
954 proto.set_pid(pid);
955 proto.set_layer_name(layerName);
956 proto.set_present_type(presentType);
957 proto.set_on_time_finish(onTimeFinish);
958 proto.set_gpu_composition(gpuComposition);
959 proto.set_jank_type(jankType);
960 proto.set_prediction_type(predictionType);
961 proto.set_is_buffer(isBuffer);
962 return proto;
963 }
964
createProtoFrameEnd(int64_t cookie)965 ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
966 ProtoFrameEnd proto;
967 proto.set_cookie(cookie);
968 return proto;
969 }
970
validateTraceEvent(const ProtoExpectedDisplayFrameStart & received,const ProtoExpectedDisplayFrameStart & source)971 void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
972 const ProtoExpectedDisplayFrameStart& source) {
973 ASSERT_TRUE(received.has_cookie());
974 EXPECT_EQ(received.cookie(), source.cookie());
975
976 ASSERT_TRUE(received.has_token());
977 EXPECT_EQ(received.token(), source.token());
978
979 ASSERT_TRUE(received.has_pid());
980 EXPECT_EQ(received.pid(), source.pid());
981 }
982
validateTraceEvent(const ProtoActualDisplayFrameStart & received,const ProtoActualDisplayFrameStart & source)983 void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
984 const ProtoActualDisplayFrameStart& source) {
985 ASSERT_TRUE(received.has_cookie());
986 EXPECT_EQ(received.cookie(), source.cookie());
987
988 ASSERT_TRUE(received.has_token());
989 EXPECT_EQ(received.token(), source.token());
990
991 ASSERT_TRUE(received.has_pid());
992 EXPECT_EQ(received.pid(), source.pid());
993
994 ASSERT_TRUE(received.has_present_type());
995 EXPECT_EQ(received.present_type(), source.present_type());
996 ASSERT_TRUE(received.has_on_time_finish());
997 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
998 ASSERT_TRUE(received.has_gpu_composition());
999 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1000 ASSERT_TRUE(received.has_jank_type());
1001 EXPECT_EQ(received.jank_type(), source.jank_type());
1002 ASSERT_TRUE(received.has_prediction_type());
1003 EXPECT_EQ(received.prediction_type(), source.prediction_type());
1004 }
1005
validateTraceEvent(const ProtoExpectedSurfaceFrameStart & received,const ProtoExpectedSurfaceFrameStart & source)1006 void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
1007 const ProtoExpectedSurfaceFrameStart& source) {
1008 ASSERT_TRUE(received.has_cookie());
1009 EXPECT_EQ(received.cookie(), source.cookie());
1010
1011 ASSERT_TRUE(received.has_token());
1012 EXPECT_EQ(received.token(), source.token());
1013
1014 ASSERT_TRUE(received.has_display_frame_token());
1015 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1016
1017 ASSERT_TRUE(received.has_pid());
1018 EXPECT_EQ(received.pid(), source.pid());
1019
1020 ASSERT_TRUE(received.has_layer_name());
1021 EXPECT_EQ(received.layer_name(), source.layer_name());
1022 }
1023
validateTraceEvent(const ProtoActualSurfaceFrameStart & received,const ProtoActualSurfaceFrameStart & source)1024 void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
1025 const ProtoActualSurfaceFrameStart& source) {
1026 ASSERT_TRUE(received.has_cookie());
1027 EXPECT_EQ(received.cookie(), source.cookie());
1028
1029 ASSERT_TRUE(received.has_token());
1030 EXPECT_EQ(received.token(), source.token());
1031
1032 ASSERT_TRUE(received.has_display_frame_token());
1033 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1034
1035 ASSERT_TRUE(received.has_pid());
1036 EXPECT_EQ(received.pid(), source.pid());
1037
1038 ASSERT_TRUE(received.has_layer_name());
1039 EXPECT_EQ(received.layer_name(), source.layer_name());
1040
1041 ASSERT_TRUE(received.has_present_type());
1042 EXPECT_EQ(received.present_type(), source.present_type());
1043 ASSERT_TRUE(received.has_on_time_finish());
1044 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1045 ASSERT_TRUE(received.has_gpu_composition());
1046 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1047 ASSERT_TRUE(received.has_jank_type());
1048 EXPECT_EQ(received.jank_type(), source.jank_type());
1049 ASSERT_TRUE(received.has_prediction_type());
1050 EXPECT_EQ(received.prediction_type(), source.prediction_type());
1051 ASSERT_TRUE(received.has_is_buffer());
1052 EXPECT_EQ(received.is_buffer(), source.is_buffer());
1053 }
1054
validateTraceEvent(const ProtoFrameEnd & received,const ProtoFrameEnd & source)1055 void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
1056 ASSERT_TRUE(received.has_cookie());
1057 EXPECT_EQ(received.cookie(), source.cookie());
1058 }
1059
TEST_F(FrameTimelineTest,traceDisplayFrame_emitsValidTracePacket)1060 TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
1061 auto tracingSession = getTracingSessionForTest();
1062 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1063
1064 tracingSession->StartBlocking();
1065
1066 // Add an empty surface frame so that display frame would get traced.
1067 addEmptySurfaceFrame();
1068 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
1069
1070 // Set up the display frame
1071 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
1072 mFrameTimeline->setSfPresent(26, presentFence1);
1073 presentFence1->signalForTest(31);
1074
1075 int64_t traceCookie = snoopCurrentTraceCookie();
1076 auto protoExpectedDisplayFrameStart =
1077 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1078 kSurfaceFlingerPid);
1079 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1080 auto protoActualDisplayFrameStart =
1081 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
1082 kSurfaceFlingerPid,
1083 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
1084 FrameTimelineEvent::JANK_NONE,
1085 FrameTimelineEvent::PREDICTION_VALID);
1086 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
1087
1088 addEmptyDisplayFrame();
1089 flushTrace();
1090 tracingSession->StopBlocking();
1091
1092 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1093 EXPECT_EQ(packets.size(), 4u);
1094
1095 // Packet - 0 : ExpectedDisplayFrameStart
1096 const auto& packet0 = packets[0];
1097 ASSERT_TRUE(packet0.has_timestamp());
1098 EXPECT_EQ(packet0.timestamp(), 10u);
1099 ASSERT_TRUE(packet0.has_frame_timeline_event());
1100
1101 const auto& event0 = packet0.frame_timeline_event();
1102 ASSERT_TRUE(event0.has_expected_display_frame_start());
1103 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
1104 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
1105
1106 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
1107 const auto& packet1 = packets[1];
1108 ASSERT_TRUE(packet1.has_timestamp());
1109 EXPECT_EQ(packet1.timestamp(), 30u);
1110 ASSERT_TRUE(packet1.has_frame_timeline_event());
1111
1112 const auto& event1 = packet1.frame_timeline_event();
1113 ASSERT_TRUE(event1.has_frame_end());
1114 const auto& expectedDisplayFrameEnd = event1.frame_end();
1115 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
1116
1117 // Packet - 2 : ActualDisplayFrameStart
1118 const auto& packet2 = packets[2];
1119 ASSERT_TRUE(packet2.has_timestamp());
1120 EXPECT_EQ(packet2.timestamp(), 20u);
1121 ASSERT_TRUE(packet2.has_frame_timeline_event());
1122
1123 const auto& event2 = packet2.frame_timeline_event();
1124 ASSERT_TRUE(event2.has_actual_display_frame_start());
1125 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1126 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1127
1128 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1129 const auto& packet3 = packets[3];
1130 ASSERT_TRUE(packet3.has_timestamp());
1131 EXPECT_EQ(packet3.timestamp(), 31u);
1132 ASSERT_TRUE(packet3.has_frame_timeline_event());
1133
1134 const auto& event3 = packet3.frame_timeline_event();
1135 ASSERT_TRUE(event3.has_frame_end());
1136 const auto& actualDisplayFrameEnd = event3.frame_end();
1137 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1138 }
1139
TEST_F(FrameTimelineTest,traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline)1140 TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1141 auto tracingSession = getTracingSessionForTest();
1142 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1143
1144 tracingSession->StartBlocking();
1145 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1146 // Flush the token so that it would expire
1147 flushTokens();
1148
1149 // Add an empty surface frame so that display frame would get traced.
1150 addEmptySurfaceFrame();
1151
1152 // Set up the display frame
1153 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
1154 mFrameTimeline->setSfPresent(26, presentFence1);
1155 presentFence1->signalForTest(31);
1156
1157 int64_t traceCookie = snoopCurrentTraceCookie();
1158
1159 auto protoActualDisplayFrameStart =
1160 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1161 kSurfaceFlingerPid,
1162 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
1163 false, FrameTimelineEvent::JANK_UNKNOWN,
1164 FrameTimelineEvent::PREDICTION_EXPIRED);
1165 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1166
1167 addEmptyDisplayFrame();
1168 flushTrace();
1169 tracingSession->StopBlocking();
1170
1171 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1172 // Only actual timeline packets should be in the trace
1173 EXPECT_EQ(packets.size(), 2u);
1174
1175 // Packet - 0 : ActualDisplayFrameStart
1176 const auto& packet0 = packets[0];
1177 ASSERT_TRUE(packet0.has_timestamp());
1178 EXPECT_EQ(packet0.timestamp(), 20u);
1179 ASSERT_TRUE(packet0.has_frame_timeline_event());
1180
1181 const auto& event0 = packet0.frame_timeline_event();
1182 ASSERT_TRUE(event0.has_actual_display_frame_start());
1183 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1184 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1185
1186 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1187 const auto& packet1 = packets[1];
1188 ASSERT_TRUE(packet1.has_timestamp());
1189 EXPECT_EQ(packet1.timestamp(), 31u);
1190 ASSERT_TRUE(packet1.has_frame_timeline_event());
1191
1192 const auto& event1 = packet1.frame_timeline_event();
1193 ASSERT_TRUE(event1.has_frame_end());
1194 const auto& actualDisplayFrameEnd = event1.frame_end();
1195 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1196 }
1197
TEST_F(FrameTimelineTest,traceSurfaceFrame_emitsValidTracePacket)1198 TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1199 auto tracingSession = getTracingSessionForTest();
1200 // Layer specific increment
1201 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
1202 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1203 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1204
1205 tracingSession->StartBlocking();
1206 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1207 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
1208
1209 FrameTimelineInfo ftInfo;
1210 ftInfo.vsyncId = surfaceFrameToken;
1211 ftInfo.inputEventId = sInputEventId;
1212
1213 auto surfaceFrame1 =
1214 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1215 sLayerNameOne, sLayerNameOne,
1216 /*isBuffer*/ true, sGameMode);
1217 auto surfaceFrame2 =
1218 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1219 sLayerNameOne, sLayerNameOne,
1220 /*isBuffer*/ true, sGameMode);
1221 surfaceFrame1->setActualQueueTime(10);
1222 surfaceFrame1->setDropTime(15);
1223
1224 surfaceFrame2->setActualQueueTime(15);
1225 surfaceFrame2->setAcquireFenceTime(20);
1226
1227 // First 2 cookies will be used by the DisplayFrame
1228 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1229
1230 auto protoDroppedSurfaceFrameExpectedStart =
1231 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1232 displayFrameToken1, sPidOne, sLayerNameOne);
1233 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1234 auto protoDroppedSurfaceFrameActualStart =
1235 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1236 displayFrameToken1, sPidOne, sLayerNameOne,
1237 FrameTimelineEvent::PRESENT_DROPPED, false, false,
1238 FrameTimelineEvent::JANK_NONE,
1239 FrameTimelineEvent::PREDICTION_VALID, true);
1240 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
1241
1242 auto protoPresentedSurfaceFrameExpectedStart =
1243 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1244 displayFrameToken1, sPidOne, sLayerNameOne);
1245 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1246 auto protoPresentedSurfaceFrameActualStart =
1247 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1248 displayFrameToken1, sPidOne, sLayerNameOne,
1249 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
1250 FrameTimelineEvent::JANK_NONE,
1251 FrameTimelineEvent::PREDICTION_VALID, true);
1252 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
1253
1254 // Set up the display frame
1255 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
1256 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1257 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1258 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1259 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1260 mFrameTimeline->setSfPresent(26, presentFence1);
1261 presentFence1->signalForTest(40);
1262
1263 addEmptyDisplayFrame();
1264 flushTrace();
1265 tracingSession->StopBlocking();
1266
1267 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1268 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1269 EXPECT_EQ(packets.size(), 12u);
1270
1271 // Packet - 4 : ExpectedSurfaceFrameStart1
1272 const auto& packet4 = packets[4];
1273 ASSERT_TRUE(packet4.has_timestamp());
1274 EXPECT_EQ(packet4.timestamp(), 10u);
1275 ASSERT_TRUE(packet4.has_frame_timeline_event());
1276
1277 const auto& event4 = packet4.frame_timeline_event();
1278 ASSERT_TRUE(event4.has_expected_surface_frame_start());
1279 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1280 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
1281
1282 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
1283 const auto& packet5 = packets[5];
1284 ASSERT_TRUE(packet5.has_timestamp());
1285 EXPECT_EQ(packet5.timestamp(), 25u);
1286 ASSERT_TRUE(packet5.has_frame_timeline_event());
1287
1288 const auto& event5 = packet5.frame_timeline_event();
1289 ASSERT_TRUE(event5.has_frame_end());
1290 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1291 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
1292
1293 // Packet - 6 : ActualSurfaceFrameStart1
1294 const auto& packet6 = packets[6];
1295 ASSERT_TRUE(packet6.has_timestamp());
1296 EXPECT_EQ(packet6.timestamp(), 10u);
1297 ASSERT_TRUE(packet6.has_frame_timeline_event());
1298
1299 const auto& event6 = packet6.frame_timeline_event();
1300 ASSERT_TRUE(event6.has_actual_surface_frame_start());
1301 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1302 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
1303
1304 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
1305 const auto& packet7 = packets[7];
1306 ASSERT_TRUE(packet7.has_timestamp());
1307 EXPECT_EQ(packet7.timestamp(), 15u);
1308 ASSERT_TRUE(packet7.has_frame_timeline_event());
1309
1310 const auto& event7 = packet7.frame_timeline_event();
1311 ASSERT_TRUE(event7.has_frame_end());
1312 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1313 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1314
1315 // Packet - 8 : ExpectedSurfaceFrameStart2
1316 const auto& packet8 = packets[8];
1317 ASSERT_TRUE(packet8.has_timestamp());
1318 EXPECT_EQ(packet8.timestamp(), 10u);
1319 ASSERT_TRUE(packet8.has_frame_timeline_event());
1320
1321 const auto& event8 = packet8.frame_timeline_event();
1322 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1323 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1324 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1325
1326 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1327 const auto& packet9 = packets[9];
1328 ASSERT_TRUE(packet9.has_timestamp());
1329 EXPECT_EQ(packet9.timestamp(), 25u);
1330 ASSERT_TRUE(packet9.has_frame_timeline_event());
1331
1332 const auto& event9 = packet9.frame_timeline_event();
1333 ASSERT_TRUE(event9.has_frame_end());
1334 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1335 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1336
1337 // Packet - 10 : ActualSurfaceFrameStart2
1338 const auto& packet10 = packets[10];
1339 ASSERT_TRUE(packet10.has_timestamp());
1340 EXPECT_EQ(packet10.timestamp(), 10u);
1341 ASSERT_TRUE(packet10.has_frame_timeline_event());
1342
1343 const auto& event10 = packet10.frame_timeline_event();
1344 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1345 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1346 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1347
1348 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1349 const auto& packet11 = packets[11];
1350 ASSERT_TRUE(packet11.has_timestamp());
1351 EXPECT_EQ(packet11.timestamp(), 20u);
1352 ASSERT_TRUE(packet11.has_frame_timeline_event());
1353
1354 const auto& event11 = packet11.frame_timeline_event();
1355 ASSERT_TRUE(event11.has_frame_end());
1356 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1357 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1358 }
1359
TEST_F(FrameTimelineTest,traceSurfaceFrame_predictionExpiredIsAppMissedDeadline)1360 TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredIsAppMissedDeadline) {
1361 auto tracingSession = getTracingSessionForTest();
1362 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1363
1364 tracingSession->StartBlocking();
1365 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1366 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1367 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
1368 int64_t surfaceFrameToken =
1369 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1370
1371 // Flush the token so that it would expire
1372 flushTokens();
1373 FrameTimelineInfo ftInfo;
1374 ftInfo.vsyncId = surfaceFrameToken;
1375 ftInfo.inputEventId = 0;
1376 auto surfaceFrame1 =
1377 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1378 sLayerNameOne, sLayerNameOne,
1379 /*isBuffer*/ true, sGameMode);
1380 surfaceFrame1->setActualQueueTime(appEndTime);
1381 surfaceFrame1->setAcquireFenceTime(appEndTime);
1382
1383 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1384 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1385 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
1386 int64_t displayFrameToken =
1387 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1388
1389 // First 2 cookies will be used by the DisplayFrame
1390 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1391
1392 auto protoActualSurfaceFrameStart =
1393 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1394 displayFrameToken, sPidOne, sLayerNameOne,
1395 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
1396 false, FrameTimelineEvent::JANK_APP_DEADLINE_MISSED,
1397 FrameTimelineEvent::PREDICTION_EXPIRED, true);
1398 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1399
1400 // Set up the display frame
1401 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1402 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1403 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1404 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1405 presentFence1->signalForTest(sfPresentTime);
1406
1407 addEmptyDisplayFrame();
1408 flushTrace();
1409 tracingSession->StopBlocking();
1410
1411 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1412 // Display Frame 4 packets + SurfaceFrame 2 packets
1413 ASSERT_EQ(packets.size(), 6u);
1414
1415 // Packet - 4 : ActualSurfaceFrameStart
1416 const auto& packet4 = packets[4];
1417 ASSERT_TRUE(packet4.has_timestamp());
1418 EXPECT_EQ(packet4.timestamp(),
1419 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1420 ASSERT_TRUE(packet4.has_frame_timeline_event());
1421
1422 const auto& event4 = packet4.frame_timeline_event();
1423 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1424 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1425 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1426
1427 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1428 const auto& packet5 = packets[5];
1429 ASSERT_TRUE(packet5.has_timestamp());
1430 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1431 ASSERT_TRUE(packet5.has_frame_timeline_event());
1432
1433 const auto& event5 = packet5.frame_timeline_event();
1434 ASSERT_TRUE(event5.has_frame_end());
1435 const auto& actualSurfaceFrameEnd = event5.frame_end();
1436 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
1437 }
1438
TEST_F(FrameTimelineTest,traceSurfaceFrame_predictionExpiredDroppedFramesTracedProperly)1439 TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDroppedFramesTracedProperly) {
1440 auto tracingSession = getTracingSessionForTest();
1441 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1442
1443 tracingSession->StartBlocking();
1444 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1445 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1446 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
1447 int64_t surfaceFrameToken =
1448 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1449
1450 // Flush the token so that it would expire
1451 flushTokens();
1452 FrameTimelineInfo ftInfo;
1453 ftInfo.vsyncId = surfaceFrameToken;
1454 ftInfo.inputEventId = 0;
1455 auto surfaceFrame1 =
1456 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1457 sLayerNameOne, sLayerNameOne,
1458 /*isBuffer*/ true, sGameMode);
1459
1460 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(22ms).count();
1461 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1462 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
1463 int64_t displayFrameToken =
1464 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1465
1466 // First 2 cookies will be used by the DisplayFrame
1467 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1468
1469 auto protoActualSurfaceFrameStart =
1470 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1471 displayFrameToken, sPidOne, sLayerNameOne,
1472 FrameTimelineEvent::PRESENT_DROPPED, false, false,
1473 FrameTimelineEvent::JANK_NONE,
1474 FrameTimelineEvent::PREDICTION_EXPIRED, true);
1475 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1476
1477 // Set up the display frame
1478 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1479 surfaceFrame1->setDropTime(sfStartTime);
1480 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1481 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1482 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1483 presentFence1->signalForTest(sfPresentTime);
1484
1485 addEmptyDisplayFrame();
1486 flushTrace();
1487 tracingSession->StopBlocking();
1488
1489 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1490 // Display Frame 4 packets + SurfaceFrame 2 packets
1491 ASSERT_EQ(packets.size(), 6u);
1492
1493 // Packet - 4 : ActualSurfaceFrameStart
1494 const auto& packet4 = packets[4];
1495 ASSERT_TRUE(packet4.has_timestamp());
1496 EXPECT_EQ(packet4.timestamp(),
1497 static_cast<uint64_t>(sfStartTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1498 ASSERT_TRUE(packet4.has_frame_timeline_event());
1499
1500 const auto& event4 = packet4.frame_timeline_event();
1501 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1502 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1503 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1504
1505 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1506 const auto& packet5 = packets[5];
1507 ASSERT_TRUE(packet5.has_timestamp());
1508 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(sfStartTime));
1509 ASSERT_TRUE(packet5.has_frame_timeline_event());
1510
1511 const auto& event5 = packet5.frame_timeline_event();
1512 ASSERT_TRUE(event5.has_frame_end());
1513 const auto& actualSurfaceFrameEnd = event5.frame_end();
1514 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
1515 }
1516
1517 // Tests for Jank classification
TEST_F(FrameTimelineTest,jankClassification_presentOnTimeDoesNotClassify)1518 TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
1519 // Layer specific increment
1520 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
1521 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1522 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
1523 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
1524 FrameTimelineInfo ftInfo;
1525 ftInfo.vsyncId = surfaceFrameToken;
1526 ftInfo.inputEventId = sInputEventId;
1527 auto surfaceFrame =
1528 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1529 sLayerNameOne, sLayerNameOne,
1530 /*isBuffer*/ true, sGameMode);
1531 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
1532 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1533 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1534 mFrameTimeline->setSfPresent(26, presentFence1);
1535 auto displayFrame = getDisplayFrame(0);
1536 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1537 presentFence1->signalForTest(29);
1538
1539 // Fences haven't been flushed yet, so it should be 0
1540 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1541 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1542
1543 addEmptyDisplayFrame();
1544 displayFrame = getDisplayFrame(0);
1545
1546 // Fences have flushed, so the present timestamps should be updated
1547 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1548 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1549 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1550 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1551 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
1552 }
1553
TEST_F(FrameTimelineTest,jankClassification_displayFrameOnTimeFinishEarlyPresent)1554 TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
1555 Fps vsyncRate = Fps::fromPeriodNsecs(11);
1556 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1557 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1558 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
1559 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
1560 mFrameTimeline->setSfPresent(26, presentFence1);
1561 auto displayFrame = getDisplayFrame(0);
1562 presentFence1->signalForTest(30);
1563
1564 // Fences for the first frame haven't been flushed yet, so it should be 0
1565 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1566
1567 // Trigger a flush by finalizing the next DisplayFrame
1568 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1569 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
1570 mFrameTimeline->setSfPresent(56, presentFence2);
1571 displayFrame = getDisplayFrame(0);
1572
1573 // Fences for the first frame have flushed, so the present timestamps should be updated
1574 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1575 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1576 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1577 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1578
1579 // Fences for the second frame haven't been flushed yet, so it should be 0
1580 auto displayFrame2 = getDisplayFrame(1);
1581 presentFence2->signalForTest(65);
1582 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1583 addEmptyDisplayFrame();
1584 displayFrame2 = getDisplayFrame(1);
1585
1586 // Fences for the second frame have flushed, so the present timestamps should be updated
1587 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1588 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1589 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1590 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1591 }
1592
TEST_F(FrameTimelineTest,jankClassification_displayFrameOnTimeFinishLatePresent)1593 TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
1594 Fps vsyncRate = Fps::fromPeriodNsecs(11);
1595 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1596 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1597 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
1598 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
1599 mFrameTimeline->setSfPresent(26, presentFence1);
1600 auto displayFrame = getDisplayFrame(0);
1601 presentFence1->signalForTest(50);
1602
1603 // Fences for the first frame haven't been flushed yet, so it should be 0
1604 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1605
1606 // Trigger a flush by finalizing the next DisplayFrame
1607 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1608 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
1609 mFrameTimeline->setSfPresent(56, presentFence2);
1610 displayFrame = getDisplayFrame(0);
1611
1612 // Fences for the first frame have flushed, so the present timestamps should be updated
1613 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1614 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1615 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1616 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1617
1618 // Fences for the second frame haven't been flushed yet, so it should be 0
1619 auto displayFrame2 = getDisplayFrame(1);
1620 presentFence2->signalForTest(75);
1621 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1622
1623 addEmptyDisplayFrame();
1624 displayFrame2 = getDisplayFrame(1);
1625
1626 // Fences for the second frame have flushed, so the present timestamps should be updated
1627 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1628 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1629 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1630 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1631 }
1632
TEST_F(FrameTimelineTest,jankClassification_displayFrameLateFinishEarlyPresent)1633 TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
1634 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1635 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
1636 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
1637
1638 mFrameTimeline->setSfPresent(22, presentFence1);
1639 auto displayFrame = getDisplayFrame(0);
1640 presentFence1->signalForTest(28);
1641
1642 // Fences haven't been flushed yet, so it should be 0
1643 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1644
1645 addEmptyDisplayFrame();
1646 displayFrame = getDisplayFrame(0);
1647
1648 // Fences have flushed, so the present timestamps should be updated
1649 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1650 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1651 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1652 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1653 }
1654
TEST_F(FrameTimelineTest,jankClassification_displayFrameLateFinishLatePresent)1655 TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
1656 /*
1657 * Case 1 - cpu time > vsync period but combined time > deadline > deadline -> cpudeadlinemissed
1658 * Case 2 - cpu time < vsync period but combined time > deadline -> gpudeadlinemissed
1659 * Case 3 - previous frame ran longer -> sf_stuffing
1660 * Case 4 - Long cpu under SF stuffing -> cpudeadlinemissed
1661 */
1662 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1663 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1664 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1665 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1666 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1667 auto gpuFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1668 auto gpuFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1669 auto gpuFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1670 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1671 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
1672 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1673 int64_t sfToken4 = mTokenManager->generateTokenForPredictions({112, 120, 120});
1674
1675 // case 1 - cpu time = 33 - 12 = 21, vsync period = 11
1676 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
1677 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
1678 auto displayFrame0 = getDisplayFrame(0);
1679 gpuFence1->signalForTest(36);
1680 presentFence1->signalForTest(52);
1681
1682 // Fences haven't been flushed yet, so it should be 0
1683 EXPECT_EQ(displayFrame0->getActuals().presentTime, 0);
1684
1685 // case 2 - cpu time = 56 - 52 = 4, vsync period = 30
1686 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(30));
1687 mFrameTimeline->setSfPresent(56, presentFence2, gpuFence2);
1688 auto displayFrame1 = getDisplayFrame(1);
1689 gpuFence2->signalForTest(76);
1690 presentFence2->signalForTest(90);
1691
1692 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1693 // Fences have flushed for first displayFrame, so the present timestamps should be updated
1694 EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
1695 EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1696 EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1697 EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
1698
1699 // case 3 - cpu time = 86 - 82 = 4, vsync period = 30
1700 mFrameTimeline->setSfWakeUp(sfToken3, 106, Fps::fromPeriodNsecs(30));
1701 mFrameTimeline->setSfPresent(112, presentFence3, gpuFence3);
1702 auto displayFrame2 = getDisplayFrame(2);
1703 gpuFence3->signalForTest(116);
1704 presentFence3->signalForTest(120);
1705
1706 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1707 // Fences have flushed for second displayFrame, so the present timestamps should be updated
1708 EXPECT_EQ(displayFrame1->getActuals().presentTime, 90);
1709 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1710 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1711 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
1712
1713 // case 4 - cpu time = 86 - 82 = 4, vsync period = 30
1714 mFrameTimeline->setSfWakeUp(sfToken4, 120, Fps::fromPeriodNsecs(30));
1715 mFrameTimeline->setSfPresent(140, presentFence4, gpuFence4);
1716 auto displayFrame3 = getDisplayFrame(3);
1717 gpuFence4->signalForTest(156);
1718 presentFence4->signalForTest(180);
1719
1720 EXPECT_EQ(displayFrame3->getActuals().presentTime, 0);
1721 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1722 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1723 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1724 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1725 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerStuffing);
1726
1727 addEmptyDisplayFrame();
1728
1729 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1730 EXPECT_EQ(displayFrame3->getActuals().presentTime, 180);
1731 EXPECT_EQ(displayFrame3->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1732 EXPECT_EQ(displayFrame3->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1733 EXPECT_EQ(displayFrame3->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
1734 }
1735
TEST_F(FrameTimelineTest,jankClassification_surfaceFrameOnTimeFinishEarlyPresent)1736 TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
1737 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
1738 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1739 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1740 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
1741 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1742 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1743 FrameTimelineInfo ftInfo;
1744 ftInfo.vsyncId = surfaceFrameToken1;
1745 ftInfo.inputEventId = sInputEventId;
1746 auto surfaceFrame1 =
1747 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1748 sLayerNameOne, sLayerNameOne,
1749 /*isBuffer*/ true, sGameMode);
1750 surfaceFrame1->setAcquireFenceTime(16);
1751 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
1752 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1753 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1754 mFrameTimeline->setSfPresent(27, presentFence1);
1755 auto displayFrame1 = getDisplayFrame(0);
1756 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1757 presentFence1->signalForTest(30);
1758
1759 // Fences for the first frame haven't been flushed yet, so it should be 0
1760 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1761 auto actuals1 = presentedSurfaceFrame1.getActuals();
1762 EXPECT_EQ(actuals1.presentTime, 0);
1763
1764 // Trigger a flush by finalizing the next DisplayFrame
1765 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1766 FrameTimelineInfo ftInfo2;
1767 ftInfo2.vsyncId = surfaceFrameToken2;
1768 ftInfo2.inputEventId = sInputEventId;
1769 auto surfaceFrame2 =
1770 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1771 sLayerNameOne, sLayerNameOne,
1772 /*isBuffer*/ true, sGameMode);
1773 surfaceFrame2->setAcquireFenceTime(36);
1774 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
1775 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1776 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1777 mFrameTimeline->setSfPresent(57, presentFence2);
1778 auto displayFrame2 = getDisplayFrame(1);
1779 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1780
1781 // Fences for the first frame have flushed, so the present timestamps should be updated
1782 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1783 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1784 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1785 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1786
1787 actuals1 = presentedSurfaceFrame1.getActuals();
1788 EXPECT_EQ(actuals1.presentTime, 30);
1789 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1790 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1791 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1792
1793 // Fences for the second frame haven't been flushed yet, so it should be 0
1794 presentFence2->signalForTest(65);
1795 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1796 auto actuals2 = presentedSurfaceFrame2.getActuals();
1797 EXPECT_EQ(actuals2.presentTime, 0);
1798
1799 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1800
1801 EXPECT_CALL(*mTimeStats,
1802 incrementJankyFrames(
1803 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
1804 sLayerNameOne, sGameMode,
1805 JankType::PredictionError, -3, 5, 0}));
1806
1807 addEmptyDisplayFrame();
1808
1809 // Fences for the second frame have flushed, so the present timestamps should be updated
1810 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1811 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1812 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1813 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1814
1815 actuals2 = presentedSurfaceFrame2.getActuals();
1816 EXPECT_EQ(actuals2.presentTime, 65);
1817 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1818 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1819 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1820 }
1821
TEST_F(FrameTimelineTest,jankClassification_surfaceFrameOnTimeFinishLatePresent)1822 TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
1823 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
1824 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1825 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1826 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
1827 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1828 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1829 FrameTimelineInfo ftInfo;
1830 ftInfo.vsyncId = surfaceFrameToken1;
1831 ftInfo.inputEventId = sInputEventId;
1832 auto surfaceFrame1 =
1833 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1834 sLayerNameOne, sLayerNameOne,
1835 /*isBuffer*/ true, sGameMode);
1836 surfaceFrame1->setAcquireFenceTime(16);
1837 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
1838 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1839 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1840 mFrameTimeline->setSfPresent(26, presentFence1);
1841 auto displayFrame1 = getDisplayFrame(0);
1842 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1843 presentFence1->signalForTest(50);
1844
1845 // Fences for the first frame haven't been flushed yet, so it should be 0
1846 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1847 auto actuals1 = presentedSurfaceFrame1.getActuals();
1848 EXPECT_EQ(actuals1.presentTime, 0);
1849
1850 // Trigger a flush by finalizing the next DisplayFrame
1851 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1852 FrameTimelineInfo ftInfo2;
1853 ftInfo2.vsyncId = surfaceFrameToken2;
1854 ftInfo2.inputEventId = sInputEventId;
1855 auto surfaceFrame2 =
1856 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1857 sLayerNameOne, sLayerNameOne,
1858 /*isBuffer*/ true, sGameMode);
1859 surfaceFrame2->setAcquireFenceTime(36);
1860 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
1861 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1862 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1863 mFrameTimeline->setSfPresent(57, presentFence2);
1864 auto displayFrame2 = getDisplayFrame(1);
1865 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1866
1867 // Fences for the first frame have flushed, so the present timestamps should be updated
1868 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1869 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1870 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1871 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1872
1873 actuals1 = presentedSurfaceFrame1.getActuals();
1874 EXPECT_EQ(actuals1.presentTime, 50);
1875 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1876 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1877 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1878
1879 // Fences for the second frame haven't been flushed yet, so it should be 0
1880 presentFence2->signalForTest(86);
1881 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1882 auto actuals2 = presentedSurfaceFrame2.getActuals();
1883 EXPECT_EQ(actuals2.presentTime, 0);
1884
1885 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1886
1887 EXPECT_CALL(*mTimeStats,
1888 incrementJankyFrames(
1889 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
1890 sLayerNameOne, sGameMode,
1891 JankType::PredictionError, -3, 5, 0}));
1892
1893 addEmptyDisplayFrame();
1894
1895 // Fences for the second frame have flushed, so the present timestamps should be updated
1896 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1897 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1898 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1899 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1900
1901 actuals2 = presentedSurfaceFrame2.getActuals();
1902 EXPECT_EQ(actuals2.presentTime, 86);
1903 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1904 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1905 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1906 }
1907
TEST_F(FrameTimelineTest,jankClassification_surfaceFrameLateFinishEarlyPresent)1908 TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
1909 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
1910
1911 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1912 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
1913 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
1914 FrameTimelineInfo ftInfo;
1915 ftInfo.vsyncId = surfaceFrameToken1;
1916 ftInfo.inputEventId = sInputEventId;
1917 auto surfaceFrame1 =
1918 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1919 sLayerNameOne, sLayerNameOne,
1920 /*isBuffer*/ true, sGameMode);
1921 surfaceFrame1->setAcquireFenceTime(40);
1922 mFrameTimeline->setSfWakeUp(sfToken1, 42, Fps::fromPeriodNsecs(11));
1923 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1924 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1925 mFrameTimeline->setSfPresent(46, presentFence1);
1926 auto displayFrame1 = getDisplayFrame(0);
1927 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1928 presentFence1->signalForTest(50);
1929
1930 // Fences for the first frame haven't been flushed yet, so it should be 0
1931 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1932 auto actuals1 = presentedSurfaceFrame1.getActuals();
1933 EXPECT_EQ(actuals1.presentTime, 0);
1934
1935 addEmptyDisplayFrame();
1936
1937 // Fences for the first frame have flushed, so the present timestamps should be updated
1938 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1939 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1940 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1941 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1942
1943 actuals1 = presentedSurfaceFrame1.getActuals();
1944 EXPECT_EQ(actuals1.presentTime, 50);
1945 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1946 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1947 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
1948 }
1949
TEST_F(FrameTimelineTest,jankClassification_surfaceFrameLateFinishLatePresent)1950 TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
1951 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as only
1952 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
1953 // jank to the SurfaceFrame along with AppDeadlineMissed.
1954
1955 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
1956 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1957 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
1958 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
1959 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1960 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
1961 FrameTimelineInfo ftInfo;
1962 ftInfo.vsyncId = surfaceFrameToken1;
1963 ftInfo.inputEventId = sInputEventId;
1964 auto surfaceFrame1 =
1965 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1966 sLayerNameOne, sLayerNameOne,
1967 /*isBuffer*/ true, sGameMode);
1968 surfaceFrame1->setAcquireFenceTime(26);
1969 mFrameTimeline->setSfWakeUp(sfToken1, 32, Fps::fromPeriodNsecs(11));
1970 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1971 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1972 mFrameTimeline->setSfPresent(36, presentFence1);
1973 auto displayFrame1 = getDisplayFrame(0);
1974 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1975 presentFence1->signalForTest(40);
1976
1977 // Fences for the first frame haven't been flushed yet, so it should be 0
1978 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1979 auto actuals1 = presentedSurfaceFrame1.getActuals();
1980 EXPECT_EQ(actuals1.presentTime, 0);
1981
1982 // Trigger a flush by finalizing the next DisplayFrame
1983 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1984 FrameTimelineInfo ftInfo2;
1985 ftInfo2.vsyncId = surfaceFrameToken2;
1986 ftInfo2.inputEventId = sInputEventId;
1987 auto surfaceFrame2 =
1988 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1989 sLayerNameOne, sLayerNameOne,
1990 /*isBuffer*/ true, sGameMode);
1991 surfaceFrame2->setAcquireFenceTime(40);
1992 mFrameTimeline->setSfWakeUp(sfToken2, 43, Fps::fromPeriodNsecs(11));
1993 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1994 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1995 mFrameTimeline->setSfPresent(56, presentFence2);
1996 auto displayFrame2 = getDisplayFrame(1);
1997 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1998
1999 // Fences for the first frame have flushed, so the present timestamps should be updated
2000 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
2001 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2002 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2003 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2004
2005 actuals1 = presentedSurfaceFrame1.getActuals();
2006 EXPECT_EQ(actuals1.presentTime, 40);
2007 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2008 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2009 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2010
2011 // Fences for the second frame haven't been flushed yet, so it should be 0
2012 presentFence2->signalForTest(60);
2013 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2014 auto actuals2 = presentedSurfaceFrame2.getActuals();
2015 EXPECT_EQ(actuals2.presentTime, 0);
2016
2017 addEmptyDisplayFrame();
2018
2019 // Fences for the second frame have flushed, so the present timestamps should be updated
2020 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
2021 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2022 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2023 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
2024
2025 actuals2 = presentedSurfaceFrame2.getActuals();
2026 EXPECT_EQ(actuals2.presentTime, 60);
2027 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2028 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2029 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2030 JankType::SurfaceFlingerCpuDeadlineMissed | JankType::AppDeadlineMissed);
2031 }
2032
TEST_F(FrameTimelineTest,jankClassification_multiJankBufferStuffingAndAppDeadlineMissed)2033 TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
2034 // Layer specific increment
2035 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
2036 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2037 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2038 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2039
2040 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2041 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
2042 FrameTimelineInfo ftInfo;
2043 ftInfo.vsyncId = surfaceFrameToken1;
2044 ftInfo.inputEventId = sInputEventId;
2045 auto surfaceFrame1 =
2046 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2047 sLayerNameOne, sLayerNameOne,
2048 /*isBuffer*/ true, sGameMode);
2049 surfaceFrame1->setAcquireFenceTime(50);
2050 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
2051 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2052 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2053 mFrameTimeline->setSfPresent(56, presentFence1);
2054 auto displayFrame1 = getDisplayFrame(0);
2055 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2056 presentFence1->signalForTest(60);
2057
2058 // Fences for the first frame haven't been flushed yet, so it should be 0
2059 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2060 auto actuals1 = presentedSurfaceFrame1.getActuals();
2061 EXPECT_EQ(actuals1.presentTime, 0);
2062
2063 // Trigger a flush by finalizing the next DisplayFrame
2064 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2065 FrameTimelineInfo ftInfo2;
2066 ftInfo2.vsyncId = surfaceFrameToken2;
2067 ftInfo2.inputEventId = sInputEventId;
2068 auto surfaceFrame2 =
2069 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2070 sLayerNameOne, sLayerNameOne,
2071 /*isBuffer*/ true, sGameMode);
2072 surfaceFrame2->setAcquireFenceTime(84);
2073 mFrameTimeline->setSfWakeUp(sfToken2, 112, Fps::fromPeriodNsecs(30));
2074 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2075 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2076 mFrameTimeline->setSfPresent(116, presentFence2);
2077 auto displayFrame2 = getDisplayFrame(1);
2078 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2079 presentFence2->signalForTest(120);
2080
2081 // Fences for the first frame have flushed, so the present timestamps should be updated
2082 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2083 actuals1 = presentedSurfaceFrame1.getActuals();
2084 EXPECT_EQ(actuals1.endTime, 50);
2085 EXPECT_EQ(actuals1.presentTime, 60);
2086
2087 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2088 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2089 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2090
2091 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2092 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2093 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2094
2095 // Fences for the second frame haven't been flushed yet, so it should be 0
2096 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2097 auto actuals2 = presentedSurfaceFrame2.getActuals();
2098 EXPECT_EQ(actuals2.presentTime, 0);
2099
2100 addEmptyDisplayFrame();
2101
2102 // Fences for the second frame have flushed, so the present timestamps should be updated
2103 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
2104 actuals2 = presentedSurfaceFrame2.getActuals();
2105 EXPECT_EQ(actuals2.presentTime, 120);
2106
2107 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2108 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2109 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
2110
2111 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2112 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2113 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2114 JankType::AppDeadlineMissed | JankType::BufferStuffing);
2115 }
2116
TEST_F(FrameTimelineTest,jankClassification_appDeadlineAdjustedForBufferStuffing)2117 TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
2118 // Layer specific increment
2119 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
2120 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2121 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2122 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2123
2124 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2125 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
2126 FrameTimelineInfo ftInfo;
2127 ftInfo.vsyncId = surfaceFrameToken1;
2128 ftInfo.inputEventId = sInputEventId;
2129 auto surfaceFrame1 =
2130 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2131 sLayerNameOne, sLayerNameOne,
2132 /*isBuffer*/ true, sGameMode);
2133 surfaceFrame1->setAcquireFenceTime(50);
2134 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
2135 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2136 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2137 mFrameTimeline->setSfPresent(56, presentFence1);
2138 auto displayFrame1 = getDisplayFrame(0);
2139 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2140 presentFence1->signalForTest(60);
2141
2142 // Fences for the first frame haven't been flushed yet, so it should be 0
2143 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2144 auto actuals1 = presentedSurfaceFrame1.getActuals();
2145 EXPECT_EQ(actuals1.presentTime, 0);
2146
2147 // Trigger a flush by finalizing the next DisplayFrame
2148 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2149 FrameTimelineInfo ftInfo2;
2150 ftInfo2.vsyncId = surfaceFrameToken2;
2151 ftInfo2.inputEventId = sInputEventId;
2152 auto surfaceFrame2 =
2153 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2154 sLayerNameOne, sLayerNameOne,
2155 /*isBuffer*/ true, sGameMode);
2156 surfaceFrame2->setAcquireFenceTime(80);
2157 mFrameTimeline->setSfWakeUp(sfToken2, 82, Fps::fromPeriodNsecs(30));
2158 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
2159 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2160 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2161 mFrameTimeline->setSfPresent(86, presentFence2);
2162 auto displayFrame2 = getDisplayFrame(1);
2163 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2164 presentFence2->signalForTest(90);
2165
2166 // Fences for the first frame have flushed, so the present timestamps should be updated
2167 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2168 actuals1 = presentedSurfaceFrame1.getActuals();
2169 EXPECT_EQ(actuals1.endTime, 50);
2170 EXPECT_EQ(actuals1.presentTime, 60);
2171
2172 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2173 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2174 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2175
2176 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2177 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2178 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2179
2180 // Fences for the second frame haven't been flushed yet, so it should be 0
2181 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2182 auto actuals2 = presentedSurfaceFrame2.getActuals();
2183 EXPECT_EQ(actuals2.presentTime, 0);
2184
2185 addEmptyDisplayFrame();
2186
2187 // Fences for the second frame have flushed, so the present timestamps should be updated
2188 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2189 actuals2 = presentedSurfaceFrame2.getActuals();
2190 EXPECT_EQ(actuals2.presentTime, 90);
2191
2192 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2193 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2194 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
2195
2196 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2197 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2198 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
2199 }
2200
TEST_F(FrameTimelineTest,jankClassification_displayFrameLateFinishLatePresent_GpuAndCpuMiss)2201 TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent_GpuAndCpuMiss) {
2202 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2203 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2204 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2205 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2206 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2207
2208 // Case 1: cpu time = 33 - 12 = 21, vsync period = 11
2209 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
2210 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
2211 auto displayFrame = getDisplayFrame(0);
2212 gpuFence1->signalForTest(36);
2213 presentFence1->signalForTest(52);
2214
2215 // Fences haven't been flushed yet, so it should be 0
2216 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
2217
2218 addEmptyDisplayFrame();
2219 displayFrame = getDisplayFrame(0);
2220
2221 // Fences have flushed, so the present timestamps should be updated
2222 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
2223 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2224 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2225 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
2226
2227 // Case 2: No GPU fence so it will not use GPU composition.
2228 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(30));
2229 mFrameTimeline->setSfPresent(66, presentFence2);
2230 auto displayFrame2 = getDisplayFrame(2); // 2 because of previous empty frame
2231 presentFence2->signalForTest(90);
2232
2233 // Fences for the frame haven't been flushed yet, so it should be 0
2234 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2235
2236 addEmptyDisplayFrame();
2237
2238 // Fences have flushed, so the present timestamps should be updated
2239 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2240 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2241 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2242 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
2243 }
2244
TEST_F(FrameTimelineTest,jankClassification_presentFenceError)2245 TEST_F(FrameTimelineTest, jankClassification_presentFenceError) {
2246 auto erroneousPresentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2247 auto erroneousPresentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2248 auto validPresentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2249 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2250 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2251 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({72, 80, 80});
2252
2253 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
2254 mFrameTimeline->setSfPresent(26, erroneousPresentFence1);
2255
2256 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
2257 mFrameTimeline->setSfPresent(60, erroneousPresentFence2);
2258
2259 mFrameTimeline->setSfWakeUp(sfToken3, 72, Fps::fromPeriodNsecs(11));
2260 mFrameTimeline->setSfPresent(80, validPresentFence);
2261
2262 erroneousPresentFence2->signalForTest(2);
2263 validPresentFence->signalForTest(80);
2264
2265 addEmptyDisplayFrame();
2266
2267 {
2268 auto displayFrame = getDisplayFrame(0);
2269 EXPECT_EQ(displayFrame->getActuals().presentTime, 26);
2270 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2271 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
2272 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
2273 }
2274 {
2275 auto displayFrame = getDisplayFrame(1);
2276 EXPECT_EQ(displayFrame->getActuals().presentTime, 60);
2277 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2278 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
2279 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
2280 }
2281 {
2282 auto displayFrame = getDisplayFrame(2);
2283 EXPECT_EQ(displayFrame->getActuals().presentTime, 80);
2284 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2285 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2286 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
2287 }
2288 }
2289
TEST_F(FrameTimelineTest,computeFps_noLayerIds_returnsZero)2290 TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
2291 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
2292 }
2293
TEST_F(FrameTimelineTest,computeFps_singleDisplayFrame_returnsZero)2294 TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
2295 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2296
2297 auto surfaceFrame1 =
2298 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
2299 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2300 /*isBuffer*/ true, sGameMode);
2301 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2302 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2303 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2304 presentFence1->signalForTest(oneHundredMs);
2305 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2306
2307 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2308 }
2309
TEST_F(FrameTimelineTest,computeFps_twoDisplayFrames_oneLayer)2310 TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
2311 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2312 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2313 auto surfaceFrame1 =
2314 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
2315 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2316 /*isBuffer*/ true, sGameMode);
2317 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2318 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2319 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2320 presentFence1->signalForTest(oneHundredMs);
2321 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2322
2323 auto surfaceFrame2 =
2324 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
2325 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2326 /*isBuffer*/ true, sGameMode);
2327 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2328 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2329 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2330 presentFence2->signalForTest(twoHundredMs);
2331 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2332
2333 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
2334 }
2335
TEST_F(FrameTimelineTest,computeFps_twoDisplayFrames_twoLayers)2336 TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
2337 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2338 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2339 auto surfaceFrame1 =
2340 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
2341 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2342 /*isBuffer*/ true, sGameMode);
2343 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2344 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2345 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2346 presentFence1->signalForTest(oneHundredMs);
2347 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2348
2349 auto surfaceFrame2 =
2350 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
2351 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
2352 /*isBuffer*/ true, sGameMode);
2353 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2354 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2355 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2356 presentFence2->signalForTest(twoHundredMs);
2357 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2358
2359 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
2360 }
2361
TEST_F(FrameTimelineTest,computeFps_filtersOutLayers)2362 TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
2363 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2364 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2365 auto surfaceFrame1 =
2366 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
2367 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2368 /*isBuffer*/ true, sGameMode);
2369 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2370 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2371 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2372 presentFence1->signalForTest(oneHundredMs);
2373 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2374
2375 auto surfaceFrame2 =
2376 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
2377 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
2378 /*isBuffer*/ true, sGameMode);
2379 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2380 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2381 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2382 presentFence2->signalForTest(twoHundredMs);
2383 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2384
2385 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2386 }
2387
TEST_F(FrameTimelineTest,computeFps_averagesOverMultipleFrames)2388 TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
2389 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2390 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2391 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2392 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2393 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
2394 auto surfaceFrame1 =
2395 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
2396 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2397 /*isBuffer*/ true, sGameMode);
2398 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2399 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2400 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2401 presentFence1->signalForTest(oneHundredMs);
2402 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2403
2404 auto surfaceFrame2 =
2405 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
2406 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2407 /*isBuffer*/ true, sGameMode);
2408 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2409 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2410 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2411 presentFence2->signalForTest(twoHundredMs);
2412 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2413
2414 auto surfaceFrame3 =
2415 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
2416 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
2417 /*isBuffer*/ true, sGameMode);
2418 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2419 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2420 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2421 presentFence3->signalForTest(threeHundredMs);
2422 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2423
2424 auto surfaceFrame4 =
2425 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
2426 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2427 /*isBuffer*/ true, sGameMode);
2428 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2429 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2430 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2431 presentFence4->signalForTest(fiveHundredMs);
2432 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2433
2434 auto surfaceFrame5 =
2435 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
2436 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2437 /*isBuffer*/ true, sGameMode);
2438 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2439 // Dropped frames will be excluded from fps computation
2440 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2441 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2442 presentFence5->signalForTest(sixHundredMs);
2443 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2444
2445 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2446 }
2447
TEST_F(FrameTimelineTest,getMinTime)2448 TEST_F(FrameTimelineTest, getMinTime) {
2449 // Use SurfaceFrame::getBaseTime to test the getMinTime.
2450 FrameTimelineInfo ftInfo;
2451
2452 // Valid prediction state test.
2453 ftInfo.vsyncId = 0L;
2454 mTokenManager->generateTokenForPredictions({10});
2455 auto surfaceFrame =
2456 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2457 sLayerNameOne, sLayerNameOne,
2458 /*isBuffer*/ true, sGameMode);
2459 ASSERT_EQ(surfaceFrame->getBaseTime(), 10);
2460
2461 // Test prediction state which is not valid.
2462 ftInfo.vsyncId = FrameTimelineInfo::INVALID_VSYNC_ID;
2463 surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2464 sLayerNameOne, sLayerNameOne,
2465 /*isBuffer*/ true, sGameMode);
2466 // Start time test.
2467 surfaceFrame->setActualStartTime(200);
2468 ASSERT_EQ(surfaceFrame->getBaseTime(), 200);
2469
2470 // End time test.
2471 surfaceFrame->setAcquireFenceTime(100);
2472 ASSERT_EQ(surfaceFrame->getBaseTime(), 100);
2473
2474 // Present time test.
2475 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2476 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2477 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2478 presentFence->signalForTest(std::chrono::nanoseconds(50ns).count());
2479 mFrameTimeline->setSfPresent(50, presentFence);
2480 ASSERT_EQ(surfaceFrame->getBaseTime(), 50);
2481 }
2482 } // namespace android::frametimeline
2483