blob: 9dd14317efd5ed0285884ea6afb967ebef6601d7 [file] [log] [blame]
Adithya Srinivasanf279e042020-08-17 14:56:27 -07001/*
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
Ady Abraham3db8a3c2023-11-20 17:53:47 -080017#include <common/test/FlagUtils.h>
Sally Qif5721252023-11-17 11:14:53 -080018#include "com_android_graphics_surfaceflinger_flags.h"
Alec Mouri9a29e672020-09-14 12:39:14 -070019#include "gmock/gmock-spec-builders.h"
20#include "mock/MockTimeStats.h"
Adithya Srinivasanf279e042020-08-17 14:56:27 -070021#undef LOG_TAG
22#define LOG_TAG "LibSurfaceFlingerUnittests"
23
24#include <FrameTimeline/FrameTimeline.h>
25#include <gtest/gtest.h>
26#include <log/log.h>
Adithya Srinivasan01189672020-10-20 14:23:05 -070027#include <perfetto/trace/trace.pb.h>
Adithya Srinivasanf279e042020-08-17 14:56:27 -070028#include <cinttypes>
29
30using namespace std::chrono_literals;
Alec Mouri363faf02021-01-29 16:34:55 -080031using testing::_;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -080032using testing::AtLeast;
Alec Mouri9a29e672020-09-14 12:39:14 -070033using testing::Contains;
Adithya Srinivasan01189672020-10-20 14:23:05 -070034using FrameTimelineEvent = perfetto::protos::FrameTimelineEvent;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000035using ProtoExpectedDisplayFrameStart =
36 perfetto::protos::FrameTimelineEvent_ExpectedDisplayFrameStart;
37using ProtoExpectedSurfaceFrameStart =
38 perfetto::protos::FrameTimelineEvent_ExpectedSurfaceFrameStart;
39using ProtoActualDisplayFrameStart = perfetto::protos::FrameTimelineEvent_ActualDisplayFrameStart;
40using ProtoActualSurfaceFrameStart = perfetto::protos::FrameTimelineEvent_ActualSurfaceFrameStart;
41using ProtoFrameEnd = perfetto::protos::FrameTimelineEvent_FrameEnd;
Adithya Srinivasan01189672020-10-20 14:23:05 -070042using ProtoPresentType = perfetto::protos::FrameTimelineEvent_PresentType;
43using ProtoJankType = perfetto::protos::FrameTimelineEvent_JankType;
Adithya Srinivasan78e58af2021-02-25 00:08:08 +000044using ProtoPredictionType = perfetto::protos::FrameTimelineEvent_PredictionType;
Alec Mouri9a29e672020-09-14 12:39:14 -070045
Adithya Srinivasanf279e042020-08-17 14:56:27 -070046namespace android::frametimeline {
47
Ady Abraham57a8ab42023-01-26 15:28:19 -080048static const std::string sLayerNameOne = "layer1";
49static const std::string sLayerNameTwo = "layer2";
50
51constexpr const uid_t sUidOne = 0;
52constexpr pid_t sPidOne = 10;
53constexpr pid_t sPidTwo = 20;
54constexpr int32_t sInputEventId = 5;
55constexpr int32_t sLayerIdOne = 1;
56constexpr int32_t sLayerIdTwo = 2;
57constexpr GameMode sGameMode = GameMode::Unsupported;
Pascal Muetschardac7bcd92023-10-03 15:05:36 +020058constexpr Fps RR_11 = Fps::fromPeriodNsecs(11);
59constexpr Fps RR_30 = Fps::fromPeriodNsecs(30);
Ady Abraham57a8ab42023-01-26 15:28:19 -080060
Adithya Srinivasanf279e042020-08-17 14:56:27 -070061class FrameTimelineTest : public testing::Test {
62public:
63 FrameTimelineTest() {
64 const ::testing::TestInfo* const test_info =
65 ::testing::UnitTest::GetInstance()->current_test_info();
66 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
67 }
68
69 ~FrameTimelineTest() {
70 const ::testing::TestInfo* const test_info =
71 ::testing::UnitTest::GetInstance()->current_test_info();
72 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
73 }
74
Adithya Srinivasan01189672020-10-20 14:23:05 -070075 static void SetUpTestSuite() {
76 // Need to initialize tracing in process for testing, and only once per test suite.
77 perfetto::TracingInitArgs args;
78 args.backends = perfetto::kInProcessBackend;
79 perfetto::Tracing::Initialize(args);
80 }
81
Adithya Srinivasanf279e042020-08-17 14:56:27 -070082 void SetUp() override {
Ady Abraham57f8e182022-03-08 15:54:33 -080083 constexpr bool kUseBootTimeClock = true;
Alec Mouri9a29e672020-09-14 12:39:14 -070084 mTimeStats = std::make_shared<mock::TimeStats>();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000085 mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats, kSurfaceFlingerPid,
Ady Abraham57f8e182022-03-08 15:54:33 -080086 kTestThresholds, !kUseBootTimeClock);
Adithya Srinivasan01189672020-10-20 14:23:05 -070087 mFrameTimeline->registerDataSource();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070088 mTokenManager = &mFrameTimeline->mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000089 mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
Adithya Srinivasan2d736322020-10-01 16:53:48 -070090 maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +000091 maxTokens = mTokenManager->kMaxTokens;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070092 }
93
Adithya Srinivasan01189672020-10-20 14:23:05 -070094 // Each tracing session can be used for a single block of Start -> Stop.
95 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
96 perfetto::TraceConfig cfg;
97 cfg.set_duration_ms(500);
98 cfg.add_buffers()->set_size_kb(1024);
99 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
100 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
101
102 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
103 tracingSession->Setup(cfg);
104 return tracingSession;
105 }
106
107 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
108 perfetto::TracingSession* tracingSession) {
109 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
110 perfetto::protos::Trace trace;
111 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
112
113 std::vector<perfetto::protos::TracePacket> packets;
114 for (const auto& packet : trace.packet()) {
115 if (!packet.has_frame_timeline_event()) {
116 continue;
117 }
118 packets.emplace_back(packet);
119 }
120 return packets;
121 }
122
Ady Abraham57a8ab42023-01-26 15:28:19 -0800123 void addEmptySurfaceFrame() {
124 auto surfaceFrame =
125 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
126 sLayerNameOne, sLayerNameOne,
127 /*isBuffer*/ false, sGameMode);
128 mFrameTimeline->addSurfaceFrame(std::move(surfaceFrame));
129 }
130
Adithya Srinivasan01189672020-10-20 14:23:05 -0700131 void addEmptyDisplayFrame() {
132 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000133 // Trigger a flushPresentFence by calling setSfPresent for the next frame
Adithya Srinivasan01189672020-10-20 14:23:05 -0700134 mFrameTimeline->setSfPresent(2500, presentFence1);
135 }
136
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000137 void flushTokens() {
138 for (size_t i = 0; i < maxTokens; i++) {
139 mTokenManager->generateTokenForPredictions({});
140 }
141 EXPECT_EQ(getPredictions().size(), maxTokens);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700142 }
143
144 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
145 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800146 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
147 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700148 }
149
150 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
151 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
152 return mFrameTimeline->mDisplayFrames[idx];
153 }
154
155 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
156 return a.startTime == b.startTime && a.endTime == b.endTime &&
157 a.presentTime == b.presentTime;
158 }
159
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000160 const std::map<int64_t, TimelineItem>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700161 return mTokenManager->mPredictions;
162 }
163
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000164 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700165 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
166 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
167 }
168
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000169 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
170
171 void flushTrace() {
172 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
173 FrameTimelineDataSource::Trace(
174 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
175 }
176
Alec Mouri9a29e672020-09-14 12:39:14 -0700177 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700178 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
179 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000180 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700181 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700182 uint32_t* maxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000183 size_t maxTokens;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000184 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasanead17162021-02-18 02:17:37 +0000185 static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan54996e22021-06-25 22:26:45 +0000186 static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(0ns).count();
Adithya Srinivasanead17162021-02-18 02:17:37 +0000187 static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800188 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
189 kDeadlineThreshold,
190 kStartThreshold};
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700191};
192
193TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
194 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000195 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000196 flushTokens();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700197 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
198 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
199
200 // token1 should have expired
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700201 EXPECT_EQ(predictions.has_value(), false);
202
203 predictions = mTokenManager->getPredictionsForToken(token2);
204 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
205}
206
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700207TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800208 auto surfaceFrame1 =
209 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000210 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000211 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -0800212 auto surfaceFrame2 =
213 mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000214 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000215 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700216 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
217 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
218}
219
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700220TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800221 auto surfaceFrame =
222 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000223 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000224 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700225 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
226}
227
228TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
229 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000230 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -0800231 FrameTimelineInfo ftInfo;
232 ftInfo.vsyncId = token1;
233 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000234 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800235 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
236 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000237 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700238
239 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
240}
241
242TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
243 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800244 FrameTimelineInfo ftInfo;
245 ftInfo.vsyncId = token1;
246 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000247 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800248 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
249 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000250 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700251
252 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
253 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
254}
255
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000256TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
257 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
258 constexpr int32_t inputEventId = 1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800259 FrameTimelineInfo ftInfo;
260 ftInfo.vsyncId = token1;
261 ftInfo.inputEventId = inputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000262 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800263 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
264 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000265 /*isBuffer*/ true, sGameMode);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000266
267 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
268}
269
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700270TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
271 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700272 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800273 FrameTimelineInfo ftInfo;
274 ftInfo.vsyncId = token1;
275 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000276 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800277 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
278 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000279 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700280
281 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200282 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000283 surfaceFrame1->setDropTime(12);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800284 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
285 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700286 mFrameTimeline->setSfPresent(25, presentFence1);
287 presentFence1->signalForTest(30);
288
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000289 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700290
291 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
292 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000293 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
294 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700295 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
296}
297
298TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800299 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800300 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700301 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
302 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700303 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800304 FrameTimelineInfo ftInfo;
305 ftInfo.vsyncId = surfaceFrameToken1;
306 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700307 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800308 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
309 sLayerNameOne, sLayerNameOne,
310 /*isBuffer*/ true, sGameMode);
Alec Mouri9a29e672020-09-14 12:39:14 -0700311 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800312 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdTwo,
313 sLayerNameTwo, sLayerNameTwo,
314 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200315 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800316 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
317 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
318 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
319 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700320 mFrameTimeline->setSfPresent(26, presentFence1);
321 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800322 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
323 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700324 presentFence1->signalForTest(42);
325
326 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800327 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700328 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
329 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
330
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000331 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700332
333 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800334 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700335 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
336 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100337 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
338 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700339}
340
341TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
342 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
343 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800344 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800345 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800346 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700347 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700348 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
349 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
350 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
351 int64_t sfToken = mTokenManager->generateTokenForPredictions(
352 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800353 FrameTimelineInfo ftInfo;
354 ftInfo.vsyncId = surfaceFrameToken;
355 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700356 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800357 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000358 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000359 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200360 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800361 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
362 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700363 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
364 presentFence->signalForTest(32 + frameTimeFactor);
365 frameTimeFactor += 30;
366 }
367 auto displayFrame0 = getDisplayFrame(0);
368
369 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800370 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700371
372 // Add one more display frame
373 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
374 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
375 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
376 int64_t sfToken = mTokenManager->generateTokenForPredictions(
377 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800378 FrameTimelineInfo ftInfo;
379 ftInfo.vsyncId = surfaceFrameToken;
380 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700381 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800382 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
383 sLayerNameOne, sLayerNameOne,
384 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200385 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800386 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
387 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700388 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
389 presentFence->signalForTest(32 + frameTimeFactor);
390 displayFrame0 = getDisplayFrame(0);
391
392 // The window should have slided by 1 now and the previous 0th display frame
393 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800394 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700395}
396
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700397TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000398 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
399 "acquireFenceAfterQueue",
400 "acquireFenceAfterQueue",
401 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700402 surfaceFrame->setActualQueueTime(123);
403 surfaceFrame->setAcquireFenceTime(456);
404 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
405}
406
407TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000408 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
409 "acquireFenceAfterQueue",
410 "acquireFenceAfterQueue",
411 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700412 surfaceFrame->setActualQueueTime(456);
413 surfaceFrame->setAcquireFenceTime(123);
414 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
415}
416
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700417TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
418 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
419 presentFence->signalForTest(2);
420
421 // Size shouldn't exceed maxDisplayFrames - 64
422 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700423 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800424 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000425 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000426 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700427 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200428 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800429 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
430 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700431 mFrameTimeline->setSfPresent(27, presentFence);
432 }
433 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
434
435 // Increase the size to 256
436 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000437 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700438
439 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700440 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800441 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000442 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000443 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700444 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200445 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800446 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
447 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700448 mFrameTimeline->setSfPresent(27, presentFence);
449 }
450 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
451
452 // Shrink the size to 128
453 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000454 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700455
456 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700457 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800458 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000459 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000460 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700461 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200462 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800463 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
464 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700465 mFrameTimeline->setSfPresent(27, presentFence);
466 }
467 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
468}
Alec Mouri9a29e672020-09-14 12:39:14 -0700469
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000470TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200471 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000472
473 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
474 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
475 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800476 FrameTimelineInfo ftInfo;
477 ftInfo.vsyncId = surfaceFrameToken1;
478 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000479
480 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800481 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
482 sLayerNameOne, sLayerNameOne,
483 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200484 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000485 surfaceFrame1->setAcquireFenceTime(20);
486 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
487 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
488
489 mFrameTimeline->setSfPresent(59, presentFence1);
490 presentFence1->signalForTest(-1);
491 addEmptyDisplayFrame();
492
493 auto displayFrame0 = getDisplayFrame(0);
Ady Abrahamfcb16862022-10-10 14:35:21 -0700494 EXPECT_EQ(displayFrame0->getActuals().presentTime, 59);
Ady Abrahamb1e10d12023-03-13 15:23:54 -0700495 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000496 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
497 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
498}
499
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800500// Tests related to TimeStats
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000501TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200502 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000503 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
504 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
505 int64_t surfaceFrameToken1 = -1;
506 int64_t sfToken1 = -1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800507 FrameTimelineInfo ftInfo;
508 ftInfo.vsyncId = surfaceFrameToken1;
509 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000510
511 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800512 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
513 sLayerNameOne, sLayerNameOne,
514 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200515 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000516 surfaceFrame1->setAcquireFenceTime(20);
517 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
518 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
519 presentFence1->signalForTest(70);
520
521 mFrameTimeline->setSfPresent(59, presentFence1);
522}
523
Alec Mouri9a29e672020-09-14 12:39:14 -0700524TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200525 Fps refreshRate = RR_11;
Alec Mouri9a29e672020-09-14 12:39:14 -0700526 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800527 incrementJankyFrames(
528 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000529 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000530 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800531 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700532 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000533 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
534 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800535 FrameTimelineInfo ftInfo;
536 ftInfo.vsyncId = surfaceFrameToken1;
537 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000538
Alec Mouri9a29e672020-09-14 12:39:14 -0700539 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800540 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
541 sLayerNameOne, sLayerNameOne,
542 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200543 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000544 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800545 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
546 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000547 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700548
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000549 mFrameTimeline->setSfPresent(62, presentFence1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700550}
551
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000552TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfGpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200553 Fps refreshRate = RR_11;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000554 EXPECT_CALL(*mTimeStats,
555 incrementJankyFrames(
556 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000557 sLayerNameOne, sGameMode,
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000558 JankType::SurfaceFlingerGpuDeadlineMissed, 4, 10,
559 0}));
560 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
561 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
562 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
563 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800564 FrameTimelineInfo ftInfo;
565 ftInfo.vsyncId = surfaceFrameToken1;
566 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000567
568 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800569 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
570 sLayerNameOne, sLayerNameOne,
571 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200572 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000573 surfaceFrame1->setAcquireFenceTime(20);
574 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
575 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
576 gpuFence1->signalForTest(64);
577 presentFence1->signalForTest(70);
578
579 mFrameTimeline->setSfPresent(59, presentFence1, gpuFence1);
580}
581
Alec Mouri9a29e672020-09-14 12:39:14 -0700582TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200583 Fps refreshRate = RR_30;
Alec Mouri9a29e672020-09-14 12:39:14 -0700584 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800585 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000586 sLayerNameOne, sGameMode,
587 JankType::DisplayHAL, -4, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800588
Alec Mouri9a29e672020-09-14 12:39:14 -0700589 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000590 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
591 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800592 FrameTimelineInfo ftInfo;
593 ftInfo.vsyncId = surfaceFrameToken1;
594 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000595
Alec Mouri9a29e672020-09-14 12:39:14 -0700596 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800597 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
598 sLayerNameOne, sLayerNameOne,
599 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200600 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800601 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000602 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800603 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000604 presentFence1->signalForTest(90);
605 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800606 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700607}
608
609TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700610 Fps refreshRate = 11_Hz;
Alec Mouri9a29e672020-09-14 12:39:14 -0700611 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000612 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000613 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000614 JankType::AppDeadlineMissed, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000615 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700616 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000617 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
618 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800619 FrameTimelineInfo ftInfo;
620 ftInfo.vsyncId = surfaceFrameToken1;
621 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000622
Alec Mouri9a29e672020-09-14 12:39:14 -0700623 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800624 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
625 sLayerNameOne, sLayerNameOne,
626 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000627 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200628 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700629
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800630 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
631 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000632 presentFence1->signalForTest(90);
633 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100634
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800635 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700636}
637
Adithya Srinivasanead17162021-02-18 02:17:37 +0000638TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000639 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000640 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000641 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000642 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000643 JankType::SurfaceFlingerScheduling,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000644 -4, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000645 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000646 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
647 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800648 FrameTimelineInfo ftInfo;
649 ftInfo.vsyncId = surfaceFrameToken1;
650 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000651
Adithya Srinivasanead17162021-02-18 02:17:37 +0000652 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800653 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
654 sLayerNameOne, sLayerNameOne,
655 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000656 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200657 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000658
659 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
660 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000661 presentFence1->signalForTest(60);
662 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000663
664 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
665}
666
667TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000668 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000669 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000670 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000671 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000672 JankType::PredictionError, -4, 5,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000673 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000674 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000675 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
676 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800677 FrameTimelineInfo ftInfo;
678 ftInfo.vsyncId = surfaceFrameToken1;
679 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000680
Adithya Srinivasanead17162021-02-18 02:17:37 +0000681 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800682 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
683 sLayerNameOne, sLayerNameOne,
684 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000685 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200686 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000687
688 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
689 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000690 presentFence1->signalForTest(65);
691 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000692
693 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
694}
695
696TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000697 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000698 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000699 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000700 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000701 JankType::BufferStuffing, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000702 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000703 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000704 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
705 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800706 FrameTimelineInfo ftInfo;
707 ftInfo.vsyncId = surfaceFrameToken1;
708 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000709
Adithya Srinivasanead17162021-02-18 02:17:37 +0000710 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800711 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
712 sLayerNameOne, sLayerNameOne,
713 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000714 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200715 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000716
717 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000718 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000719 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000720 presentFence1->signalForTest(90);
721 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000722
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000723 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000724}
725
Alec Mouri363faf02021-01-29 16:34:55 -0800726TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200727 Fps refreshRate = RR_11;
728 Fps renderRate = RR_30;
Alec Mouri363faf02021-01-29 16:34:55 -0800729 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000730 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne,
731 sLayerNameOne, sGameMode,
732 JankType::AppDeadlineMissed, -4, 0,
733 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800734 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000735 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
736 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800737 FrameTimelineInfo ftInfo;
738 ftInfo.vsyncId = surfaceFrameToken1;
739 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000740
Alec Mouri363faf02021-01-29 16:34:55 -0800741 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800742 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
743 sLayerNameOne, sLayerNameOne,
744 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000745 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200746 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800747
748 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
749 surfaceFrame1->setRenderRate(renderRate);
750 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000751 presentFence1->signalForTest(90);
752 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800753
754 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
755}
756
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000757TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200758 Fps refreshRate = RR_11;
759 Fps renderRate = RR_30;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000760
761 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000762 incrementJankyFrames(
763 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000764 sGameMode,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000765 JankType::Unknown | JankType::AppDeadlineMissed,
Adithya Srinivasande272452021-04-10 00:21:00 +0000766 0, 0, 25}));
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000767 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
768 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
769 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800770 FrameTimelineInfo ftInfo;
771 ftInfo.vsyncId = surfaceFrameToken1;
772 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000773
774 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800775 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
776 sLayerNameOne, sLayerNameOne,
777 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000778 surfaceFrame1->setAcquireFenceTime(45);
779 // Trigger a prediction expiry
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000780 flushTokens();
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200781 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000782
783 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
784 surfaceFrame1->setRenderRate(renderRate);
785 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
786 presentFence1->signalForTest(90);
787 mFrameTimeline->setSfPresent(86, presentFence1);
788
789 auto displayFrame = getDisplayFrame(0);
790 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
791 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
792 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
793 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
794
795 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000796 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000797}
798
Adithya Srinivasan01189672020-10-20 14:23:05 -0700799/*
800 * Tracing Tests
801 *
802 * Trace packets are flushed all the way only when the next packet is traced.
803 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
804 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
805 * will have additional empty frames created for this reason.
806 */
807TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
808 auto tracingSession = getTracingSessionForTest();
809 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700810 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800811 FrameTimelineInfo ftInfo;
812 ftInfo.vsyncId = token1;
813 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000814 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800815 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
816 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000817 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700818
819 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200820 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800821 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
822 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700823 mFrameTimeline->setSfPresent(25, presentFence1);
824 presentFence1->signalForTest(30);
825
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000826 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700827
828 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000829 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700830}
831
832TEST_F(FrameTimelineTest, tracing_sanityTest) {
833 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800834 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800835 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700836 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700837
838 tracingSession->StartBlocking();
839 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
840 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800841 FrameTimelineInfo ftInfo;
842 ftInfo.vsyncId = token1;
843 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000844 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800845 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
846 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000847 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700848
849 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200850 mFrameTimeline->setSfWakeUp(token2, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800851 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
852 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700853 mFrameTimeline->setSfPresent(25, presentFence1);
854 presentFence1->signalForTest(30);
855
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000856 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000857 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700858 tracingSession->StopBlocking();
859
860 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000861 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000862 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700863}
864
865TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
866 auto tracingSession = getTracingSessionForTest();
867 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700868
869 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700870
871 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200872 mFrameTimeline->setSfWakeUp(-1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700873 mFrameTimeline->setSfPresent(25, presentFence1);
874 presentFence1->signalForTest(30);
875
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000876 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000877 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700878 tracingSession->StopBlocking();
879
880 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000881 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700882}
883
884TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
885 auto tracingSession = getTracingSessionForTest();
886 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700887
888 tracingSession->StartBlocking();
889 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -0800890 auto surfaceFrame1 =
891 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000892 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000893 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700894
895 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200896 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800897 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
898 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700899 mFrameTimeline->setSfPresent(25, presentFence1);
900 presentFence1->signalForTest(30);
901
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000902 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000903 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700904 tracingSession->StopBlocking();
905
906 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000907 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
908 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000909 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700910}
911
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000912ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
913 pid_t pid) {
914 ProtoExpectedDisplayFrameStart proto;
915 proto.set_cookie(cookie);
916 proto.set_token(token);
917 proto.set_pid(pid);
918 return proto;
919}
920
921ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
922 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000923 bool gpuComposition, ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000924 ProtoActualDisplayFrameStart proto;
925 proto.set_cookie(cookie);
926 proto.set_token(token);
927 proto.set_pid(pid);
928 proto.set_present_type(presentType);
929 proto.set_on_time_finish(onTimeFinish);
930 proto.set_gpu_composition(gpuComposition);
931 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000932 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000933 return proto;
934}
935
936ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
937 int64_t displayFrameToken,
938 pid_t pid,
939 std::string layerName) {
940 ProtoExpectedSurfaceFrameStart proto;
941 proto.set_cookie(cookie);
942 proto.set_token(token);
943 proto.set_display_frame_token(displayFrameToken);
944 proto.set_pid(pid);
945 proto.set_layer_name(layerName);
946 return proto;
947}
948
949ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
950 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
951 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +0000952 ProtoJankType jankType, ProtoPredictionType predictionType, bool isBuffer) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000953 ProtoActualSurfaceFrameStart proto;
954 proto.set_cookie(cookie);
955 proto.set_token(token);
956 proto.set_display_frame_token(displayFrameToken);
957 proto.set_pid(pid);
958 proto.set_layer_name(layerName);
959 proto.set_present_type(presentType);
960 proto.set_on_time_finish(onTimeFinish);
961 proto.set_gpu_composition(gpuComposition);
962 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000963 proto.set_prediction_type(predictionType);
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +0000964 proto.set_is_buffer(isBuffer);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000965 return proto;
966}
967
968ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
969 ProtoFrameEnd proto;
970 proto.set_cookie(cookie);
971 return proto;
972}
973
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000974void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
975 const ProtoExpectedDisplayFrameStart& source) {
976 ASSERT_TRUE(received.has_cookie());
977 EXPECT_EQ(received.cookie(), source.cookie());
978
Adithya Srinivasan01189672020-10-20 14:23:05 -0700979 ASSERT_TRUE(received.has_token());
980 EXPECT_EQ(received.token(), source.token());
981
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000982 ASSERT_TRUE(received.has_pid());
983 EXPECT_EQ(received.pid(), source.pid());
984}
985
986void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
987 const ProtoActualDisplayFrameStart& source) {
988 ASSERT_TRUE(received.has_cookie());
989 EXPECT_EQ(received.cookie(), source.cookie());
990
991 ASSERT_TRUE(received.has_token());
992 EXPECT_EQ(received.token(), source.token());
993
994 ASSERT_TRUE(received.has_pid());
995 EXPECT_EQ(received.pid(), source.pid());
996
Adithya Srinivasan01189672020-10-20 14:23:05 -0700997 ASSERT_TRUE(received.has_present_type());
998 EXPECT_EQ(received.present_type(), source.present_type());
999 ASSERT_TRUE(received.has_on_time_finish());
1000 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1001 ASSERT_TRUE(received.has_gpu_composition());
1002 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1003 ASSERT_TRUE(received.has_jank_type());
1004 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001005 ASSERT_TRUE(received.has_prediction_type());
1006 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001007}
1008
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001009void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
1010 const ProtoExpectedSurfaceFrameStart& source) {
1011 ASSERT_TRUE(received.has_cookie());
1012 EXPECT_EQ(received.cookie(), source.cookie());
1013
Adithya Srinivasan01189672020-10-20 14:23:05 -07001014 ASSERT_TRUE(received.has_token());
1015 EXPECT_EQ(received.token(), source.token());
1016
1017 ASSERT_TRUE(received.has_display_frame_token());
1018 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1019
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001020 ASSERT_TRUE(received.has_pid());
1021 EXPECT_EQ(received.pid(), source.pid());
1022
1023 ASSERT_TRUE(received.has_layer_name());
1024 EXPECT_EQ(received.layer_name(), source.layer_name());
1025}
1026
1027void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
1028 const ProtoActualSurfaceFrameStart& source) {
1029 ASSERT_TRUE(received.has_cookie());
1030 EXPECT_EQ(received.cookie(), source.cookie());
1031
1032 ASSERT_TRUE(received.has_token());
1033 EXPECT_EQ(received.token(), source.token());
1034
1035 ASSERT_TRUE(received.has_display_frame_token());
1036 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1037
1038 ASSERT_TRUE(received.has_pid());
1039 EXPECT_EQ(received.pid(), source.pid());
1040
1041 ASSERT_TRUE(received.has_layer_name());
1042 EXPECT_EQ(received.layer_name(), source.layer_name());
1043
Adithya Srinivasan01189672020-10-20 14:23:05 -07001044 ASSERT_TRUE(received.has_present_type());
1045 EXPECT_EQ(received.present_type(), source.present_type());
1046 ASSERT_TRUE(received.has_on_time_finish());
1047 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1048 ASSERT_TRUE(received.has_gpu_composition());
1049 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1050 ASSERT_TRUE(received.has_jank_type());
1051 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001052 ASSERT_TRUE(received.has_prediction_type());
1053 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001054 ASSERT_TRUE(received.has_is_buffer());
1055 EXPECT_EQ(received.is_buffer(), source.is_buffer());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001056}
Adithya Srinivasan01189672020-10-20 14:23:05 -07001057
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001058void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
1059 ASSERT_TRUE(received.has_cookie());
1060 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001061}
1062
Sally Qiaa107742023-09-29 14:53:14 -07001063TEST_F(FrameTimelineTest, traceDisplayFrameSkipped) {
Sally Qif5721252023-11-17 11:14:53 -08001064 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::add_sf_skipped_frames_to_trace,
1065 true);
1066
Sally Qiaa107742023-09-29 14:53:14 -07001067 // setup 2 display frames
1068 // DF 1: [22,40] -> [5, 40]
1069 // DF : [36, 70] (Skipped one, added by the trace)
1070 // DF 2: [82, 100] -> SF [25, 70]
1071 auto tracingSession = getTracingSessionForTest();
1072 tracingSession->StartBlocking();
1073 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1074 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 100});
1075 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1076 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1077 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1078
1079 int64_t traceCookie = snoopCurrentTraceCookie();
1080
1081 // set up 1st display frame
1082 FrameTimelineInfo ftInfo1;
1083 ftInfo1.vsyncId = surfaceFrameToken1;
1084 ftInfo1.inputEventId = sInputEventId;
1085 auto surfaceFrame1 =
1086 mFrameTimeline->createSurfaceFrameForToken(ftInfo1, sPidOne, sUidOne, sLayerIdOne,
1087 sLayerNameOne, sLayerNameOne,
1088 /*isBuffer*/ true, sGameMode);
1089 surfaceFrame1->setAcquireFenceTime(16);
1090 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_30);
1091 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1092 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1093 mFrameTimeline->setSfPresent(30, presentFence1);
1094 presentFence1->signalForTest(40);
1095
1096 // Trigger a flush by finalizing the next DisplayFrame
1097 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1098 FrameTimelineInfo ftInfo2;
1099 ftInfo2.vsyncId = surfaceFrameToken2;
1100 ftInfo2.inputEventId = sInputEventId;
1101 auto surfaceFrame2 =
1102 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1103 sLayerNameOne, sLayerNameOne,
1104 /*isBuffer*/ true, sGameMode);
1105
1106 // set up 2nd display frame
1107 surfaceFrame2->setAcquireFenceTime(36);
1108 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_11, RR_30);
1109 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1110 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1111 mFrameTimeline->setSfPresent(90, presentFence2);
1112 presentFence2->signalForTest(100);
1113
1114 // the token of skipped Display Frame
1115 auto protoSkippedActualDisplayFrameStart =
1116 createProtoActualDisplayFrameStart(traceCookie + 9, 0, kSurfaceFlingerPid,
1117 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1118 FrameTimelineEvent::JANK_DROPPED,
1119 FrameTimelineEvent::PREDICTION_VALID);
1120 auto protoSkippedActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 9);
1121
1122 // Trigger a flush by finalizing the next DisplayFrame
1123 addEmptyDisplayFrame();
1124 flushTrace();
1125 tracingSession->StopBlocking();
1126
1127 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1128 // 8 Valid Display Frames + 8 Valid Surface Frames + 2 Skipped Display Frames
1129 EXPECT_EQ(packets.size(), 18u);
1130
1131 // Packet - 16: Actual skipped Display Frame Start
1132 // the timestamp should be equal to the 2nd expected surface frame's end time
1133 const auto& packet16 = packets[16];
1134 ASSERT_TRUE(packet16.has_timestamp());
1135 EXPECT_EQ(packet16.timestamp(), 36u);
1136 ASSERT_TRUE(packet16.has_frame_timeline_event());
1137
1138 const auto& event16 = packet16.frame_timeline_event();
1139 const auto& actualSkippedDisplayFrameStart = event16.actual_display_frame_start();
1140 validateTraceEvent(actualSkippedDisplayFrameStart, protoSkippedActualDisplayFrameStart);
1141
1142 // Packet - 17: Actual skipped Display Frame End
1143 // the timestamp should be equal to the 2nd expected surface frame's present time
1144 const auto& packet17 = packets[17];
1145 ASSERT_TRUE(packet17.has_timestamp());
1146 EXPECT_EQ(packet17.timestamp(), 70u);
1147 ASSERT_TRUE(packet17.has_frame_timeline_event());
1148
1149 const auto& event17 = packet17.frame_timeline_event();
1150 const auto& actualSkippedDisplayFrameEnd = event17.frame_end();
1151 validateTraceEvent(actualSkippedDisplayFrameEnd, protoSkippedActualDisplayFrameEnd);
1152}
1153
Adithya Srinivasan01189672020-10-20 14:23:05 -07001154TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
1155 auto tracingSession = getTracingSessionForTest();
1156 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001157
1158 tracingSession->StartBlocking();
Ady Abraham57a8ab42023-01-26 15:28:19 -08001159
1160 // Add an empty surface frame so that display frame would get traced.
1161 addEmptySurfaceFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001162 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001163
1164 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001165 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001166 mFrameTimeline->setSfPresent(26, presentFence1);
1167 presentFence1->signalForTest(31);
1168
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001169 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001170 auto protoExpectedDisplayFrameStart =
1171 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1172 kSurfaceFlingerPid);
1173 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1174 auto protoActualDisplayFrameStart =
1175 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
1176 kSurfaceFlingerPid,
1177 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001178 FrameTimelineEvent::JANK_NONE,
1179 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001180 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001181
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001182 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001183 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001184 tracingSession->StopBlocking();
1185
1186 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001187 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001188
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001189 // Packet - 0 : ExpectedDisplayFrameStart
1190 const auto& packet0 = packets[0];
1191 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001192 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001193 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001194
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001195 const auto& event0 = packet0.frame_timeline_event();
1196 ASSERT_TRUE(event0.has_expected_display_frame_start());
1197 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
1198 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
1199
1200 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
1201 const auto& packet1 = packets[1];
1202 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001203 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001204 ASSERT_TRUE(packet1.has_frame_timeline_event());
1205
1206 const auto& event1 = packet1.frame_timeline_event();
1207 ASSERT_TRUE(event1.has_frame_end());
1208 const auto& expectedDisplayFrameEnd = event1.frame_end();
1209 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
1210
1211 // Packet - 2 : ActualDisplayFrameStart
1212 const auto& packet2 = packets[2];
1213 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001214 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001215 ASSERT_TRUE(packet2.has_frame_timeline_event());
1216
1217 const auto& event2 = packet2.frame_timeline_event();
1218 ASSERT_TRUE(event2.has_actual_display_frame_start());
1219 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1220 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1221
1222 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1223 const auto& packet3 = packets[3];
1224 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001225 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001226 ASSERT_TRUE(packet3.has_frame_timeline_event());
1227
1228 const auto& event3 = packet3.frame_timeline_event();
1229 ASSERT_TRUE(event3.has_frame_end());
1230 const auto& actualDisplayFrameEnd = event3.frame_end();
1231 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001232}
1233
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001234TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1235 auto tracingSession = getTracingSessionForTest();
1236 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1237
1238 tracingSession->StartBlocking();
1239 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1240 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001241 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001242
Ady Abraham57a8ab42023-01-26 15:28:19 -08001243 // Add an empty surface frame so that display frame would get traced.
1244 addEmptySurfaceFrame();
1245
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001246 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001247 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001248 mFrameTimeline->setSfPresent(26, presentFence1);
1249 presentFence1->signalForTest(31);
1250
1251 int64_t traceCookie = snoopCurrentTraceCookie();
1252
1253 auto protoActualDisplayFrameStart =
1254 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1255 kSurfaceFlingerPid,
1256 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001257 false, FrameTimelineEvent::JANK_UNKNOWN,
1258 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001259 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1260
1261 addEmptyDisplayFrame();
1262 flushTrace();
1263 tracingSession->StopBlocking();
1264
1265 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1266 // Only actual timeline packets should be in the trace
1267 EXPECT_EQ(packets.size(), 2u);
1268
1269 // Packet - 0 : ActualDisplayFrameStart
1270 const auto& packet0 = packets[0];
1271 ASSERT_TRUE(packet0.has_timestamp());
1272 EXPECT_EQ(packet0.timestamp(), 20u);
1273 ASSERT_TRUE(packet0.has_frame_timeline_event());
1274
1275 const auto& event0 = packet0.frame_timeline_event();
1276 ASSERT_TRUE(event0.has_actual_display_frame_start());
1277 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1278 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1279
1280 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1281 const auto& packet1 = packets[1];
1282 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001283 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001284 ASSERT_TRUE(packet1.has_frame_timeline_event());
1285
1286 const auto& event1 = packet1.frame_timeline_event();
1287 ASSERT_TRUE(event1.has_frame_end());
1288 const auto& actualDisplayFrameEnd = event1.frame_end();
1289 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1290}
1291
Adithya Srinivasan01189672020-10-20 14:23:05 -07001292TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1293 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001294 // Layer specific increment
Edgar Arriaga631e4252023-03-02 02:11:24 +00001295 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001296 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1297 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1298
1299 tracingSession->StartBlocking();
1300 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1301 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001302
Huihong Luo3bdef862022-03-03 11:57:19 -08001303 FrameTimelineInfo ftInfo;
1304 ftInfo.vsyncId = surfaceFrameToken;
1305 ftInfo.inputEventId = sInputEventId;
1306
Adithya Srinivasan01189672020-10-20 14:23:05 -07001307 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001308 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1309 sLayerNameOne, sLayerNameOne,
1310 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001311 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001312 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1313 sLayerNameOne, sLayerNameOne,
1314 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001315 surfaceFrame1->setActualQueueTime(10);
1316 surfaceFrame1->setDropTime(15);
1317
1318 surfaceFrame2->setActualQueueTime(15);
1319 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001320
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001321 // First 2 cookies will be used by the DisplayFrame
1322 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1323
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001324 auto protoDroppedSurfaceFrameExpectedStart =
1325 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1326 displayFrameToken1, sPidOne, sLayerNameOne);
1327 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1328 auto protoDroppedSurfaceFrameActualStart =
1329 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1330 displayFrameToken1, sPidOne, sLayerNameOne,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001331 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1332 FrameTimelineEvent::JANK_DROPPED,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001333 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001334 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001335
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001336 auto protoPresentedSurfaceFrameExpectedStart =
1337 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1338 displayFrameToken1, sPidOne, sLayerNameOne);
1339 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1340 auto protoPresentedSurfaceFrameActualStart =
1341 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1342 displayFrameToken1, sPidOne, sLayerNameOne,
1343 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001344 FrameTimelineEvent::JANK_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001345 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001346 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001347
1348 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001349 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001350 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1351 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001352 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001353 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001354 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001355 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001356
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001357 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001358 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001359 tracingSession->StopBlocking();
1360
1361 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001362 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1363 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001364
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001365 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001366 const auto& packet4 = packets[4];
1367 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001368 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001369 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001370
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001371 const auto& event4 = packet4.frame_timeline_event();
1372 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001373 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1374 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001375
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001376 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001377 const auto& packet5 = packets[5];
1378 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001379 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001380 ASSERT_TRUE(packet5.has_frame_timeline_event());
1381
1382 const auto& event5 = packet5.frame_timeline_event();
1383 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001384 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1385 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001386
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001387 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001388 const auto& packet6 = packets[6];
1389 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001390 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001391 ASSERT_TRUE(packet6.has_frame_timeline_event());
1392
1393 const auto& event6 = packet6.frame_timeline_event();
1394 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001395 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1396 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001397
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001398 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001399 const auto& packet7 = packets[7];
1400 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001401 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001402 ASSERT_TRUE(packet7.has_frame_timeline_event());
1403
1404 const auto& event7 = packet7.frame_timeline_event();
1405 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001406 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1407 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1408
1409 // Packet - 8 : ExpectedSurfaceFrameStart2
1410 const auto& packet8 = packets[8];
1411 ASSERT_TRUE(packet8.has_timestamp());
1412 EXPECT_EQ(packet8.timestamp(), 10u);
1413 ASSERT_TRUE(packet8.has_frame_timeline_event());
1414
1415 const auto& event8 = packet8.frame_timeline_event();
1416 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1417 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1418 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1419
1420 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1421 const auto& packet9 = packets[9];
1422 ASSERT_TRUE(packet9.has_timestamp());
1423 EXPECT_EQ(packet9.timestamp(), 25u);
1424 ASSERT_TRUE(packet9.has_frame_timeline_event());
1425
1426 const auto& event9 = packet9.frame_timeline_event();
1427 ASSERT_TRUE(event9.has_frame_end());
1428 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1429 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1430
1431 // Packet - 10 : ActualSurfaceFrameStart2
1432 const auto& packet10 = packets[10];
1433 ASSERT_TRUE(packet10.has_timestamp());
1434 EXPECT_EQ(packet10.timestamp(), 10u);
1435 ASSERT_TRUE(packet10.has_frame_timeline_event());
1436
1437 const auto& event10 = packet10.frame_timeline_event();
1438 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1439 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1440 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1441
1442 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1443 const auto& packet11 = packets[11];
1444 ASSERT_TRUE(packet11.has_timestamp());
1445 EXPECT_EQ(packet11.timestamp(), 20u);
1446 ASSERT_TRUE(packet11.has_frame_timeline_event());
1447
1448 const auto& event11 = packet11.frame_timeline_event();
1449 ASSERT_TRUE(event11.has_frame_end());
1450 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1451 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1452}
1453
Ady Abrahame43ff722022-02-15 14:44:25 -08001454TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredIsAppMissedDeadline) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001455 auto tracingSession = getTracingSessionForTest();
1456 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1457
1458 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001459 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1460 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1461 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001462 int64_t surfaceFrameToken =
1463 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1464
1465 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001466 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001467 FrameTimelineInfo ftInfo;
1468 ftInfo.vsyncId = surfaceFrameToken;
1469 ftInfo.inputEventId = 0;
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001470 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001471 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1472 sLayerNameOne, sLayerNameOne,
1473 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001474 surfaceFrame1->setActualQueueTime(appEndTime);
1475 surfaceFrame1->setAcquireFenceTime(appEndTime);
1476
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001477 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1478 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1479 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001480 int64_t displayFrameToken =
1481 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1482
1483 // First 2 cookies will be used by the DisplayFrame
1484 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1485
1486 auto protoActualSurfaceFrameStart =
1487 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1488 displayFrameToken, sPidOne, sLayerNameOne,
1489 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Ady Abrahame43ff722022-02-15 14:44:25 -08001490 false, FrameTimelineEvent::JANK_APP_DEADLINE_MISSED,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001491 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001492 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1493
1494 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001495 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001496 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1497 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1498 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1499 presentFence1->signalForTest(sfPresentTime);
1500
1501 addEmptyDisplayFrame();
1502 flushTrace();
1503 tracingSession->StopBlocking();
1504
1505 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1506 // Display Frame 4 packets + SurfaceFrame 2 packets
1507 ASSERT_EQ(packets.size(), 6u);
1508
1509 // Packet - 4 : ActualSurfaceFrameStart
1510 const auto& packet4 = packets[4];
1511 ASSERT_TRUE(packet4.has_timestamp());
1512 EXPECT_EQ(packet4.timestamp(),
1513 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1514 ASSERT_TRUE(packet4.has_frame_timeline_event());
1515
1516 const auto& event4 = packet4.frame_timeline_event();
1517 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1518 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1519 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1520
1521 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1522 const auto& packet5 = packets[5];
1523 ASSERT_TRUE(packet5.has_timestamp());
1524 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1525 ASSERT_TRUE(packet5.has_frame_timeline_event());
1526
1527 const auto& event5 = packet5.frame_timeline_event();
1528 ASSERT_TRUE(event5.has_frame_end());
1529 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001530 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001531}
1532
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001533TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDroppedFramesTracedProperly) {
1534 auto tracingSession = getTracingSessionForTest();
1535 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1536
1537 tracingSession->StartBlocking();
1538 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1539 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1540 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
1541 int64_t surfaceFrameToken =
1542 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1543
1544 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001545 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001546 FrameTimelineInfo ftInfo;
1547 ftInfo.vsyncId = surfaceFrameToken;
1548 ftInfo.inputEventId = 0;
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001549 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001550 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1551 sLayerNameOne, sLayerNameOne,
1552 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001553
1554 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(22ms).count();
1555 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1556 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
1557 int64_t displayFrameToken =
1558 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1559
1560 // First 2 cookies will be used by the DisplayFrame
1561 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1562
1563 auto protoActualSurfaceFrameStart =
1564 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1565 displayFrameToken, sPidOne, sLayerNameOne,
1566 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001567 FrameTimelineEvent::JANK_DROPPED,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001568 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001569 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1570
1571 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001572 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001573 surfaceFrame1->setDropTime(sfStartTime);
1574 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1575 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1576 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1577 presentFence1->signalForTest(sfPresentTime);
1578
1579 addEmptyDisplayFrame();
1580 flushTrace();
1581 tracingSession->StopBlocking();
1582
1583 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1584 // Display Frame 4 packets + SurfaceFrame 2 packets
1585 ASSERT_EQ(packets.size(), 6u);
1586
1587 // Packet - 4 : ActualSurfaceFrameStart
1588 const auto& packet4 = packets[4];
1589 ASSERT_TRUE(packet4.has_timestamp());
1590 EXPECT_EQ(packet4.timestamp(),
1591 static_cast<uint64_t>(sfStartTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1592 ASSERT_TRUE(packet4.has_frame_timeline_event());
1593
1594 const auto& event4 = packet4.frame_timeline_event();
1595 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1596 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1597 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1598
1599 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1600 const auto& packet5 = packets[5];
1601 ASSERT_TRUE(packet5.has_timestamp());
1602 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(sfStartTime));
1603 ASSERT_TRUE(packet5.has_frame_timeline_event());
1604
1605 const auto& event5 = packet5.frame_timeline_event();
1606 ASSERT_TRUE(event5.has_frame_end());
1607 const auto& actualSurfaceFrameEnd = event5.frame_end();
1608 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
1609}
1610
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001611// Tests for Jank classification
1612TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001613 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001614 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001615 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1616 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001617 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -08001618 FrameTimelineInfo ftInfo;
1619 ftInfo.vsyncId = surfaceFrameToken;
1620 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001621 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -08001622 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1623 sLayerNameOne, sLayerNameOne,
1624 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001625 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001626 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1627 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1628 mFrameTimeline->setSfPresent(26, presentFence1);
1629 auto displayFrame = getDisplayFrame(0);
1630 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1631 presentFence1->signalForTest(29);
1632
1633 // Fences haven't been flushed yet, so it should be 0
1634 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1635 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1636
1637 addEmptyDisplayFrame();
1638 displayFrame = getDisplayFrame(0);
1639
1640 // Fences have flushed, so the present timestamps should be updated
1641 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1642 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1643 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1644 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1645 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
1646}
1647
1648TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001649 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001650 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001651 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1652 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001653 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001654 mFrameTimeline->setSfPresent(26, presentFence1);
1655 auto displayFrame = getDisplayFrame(0);
1656 presentFence1->signalForTest(30);
1657
1658 // Fences for the first frame haven't been flushed yet, so it should be 0
1659 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1660
1661 // Trigger a flush by finalizing the next DisplayFrame
1662 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001663 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001664 mFrameTimeline->setSfPresent(56, presentFence2);
1665 displayFrame = getDisplayFrame(0);
1666
1667 // Fences for the first frame have flushed, so the present timestamps should be updated
1668 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1669 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1670 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1671 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1672
1673 // Fences for the second frame haven't been flushed yet, so it should be 0
1674 auto displayFrame2 = getDisplayFrame(1);
1675 presentFence2->signalForTest(65);
1676 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001677 addEmptyDisplayFrame();
1678 displayFrame2 = getDisplayFrame(1);
1679
1680 // Fences for the second frame have flushed, so the present timestamps should be updated
1681 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1682 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1683 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1684 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1685}
1686
1687TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001688 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001689 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001690 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1691 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001692 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001693 mFrameTimeline->setSfPresent(26, presentFence1);
1694 auto displayFrame = getDisplayFrame(0);
1695 presentFence1->signalForTest(50);
1696
1697 // Fences for the first frame haven't been flushed yet, so it should be 0
1698 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1699
1700 // Trigger a flush by finalizing the next DisplayFrame
1701 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001702 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001703 mFrameTimeline->setSfPresent(56, presentFence2);
1704 displayFrame = getDisplayFrame(0);
1705
1706 // Fences for the first frame have flushed, so the present timestamps should be updated
1707 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1708 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1709 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1710 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1711
1712 // Fences for the second frame haven't been flushed yet, so it should be 0
1713 auto displayFrame2 = getDisplayFrame(1);
1714 presentFence2->signalForTest(75);
1715 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1716
1717 addEmptyDisplayFrame();
1718 displayFrame2 = getDisplayFrame(1);
1719
1720 // Fences for the second frame have flushed, so the present timestamps should be updated
1721 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1722 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1723 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1724 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1725}
1726
1727TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001728 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1729 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001730 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001731
1732 mFrameTimeline->setSfPresent(22, presentFence1);
1733 auto displayFrame = getDisplayFrame(0);
1734 presentFence1->signalForTest(28);
1735
1736 // Fences haven't been flushed yet, so it should be 0
1737 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1738
1739 addEmptyDisplayFrame();
1740 displayFrame = getDisplayFrame(0);
1741
1742 // Fences have flushed, so the present timestamps should be updated
1743 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1744 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1745 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1746 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1747}
1748
1749TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001750 /*
1751 * Case 1 - cpu time > vsync period but combined time > deadline > deadline -> cpudeadlinemissed
1752 * Case 2 - cpu time < vsync period but combined time > deadline -> gpudeadlinemissed
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001753 * Case 3 - previous frame ran longer -> sf_stuffing
1754 * Case 4 - Long cpu under SF stuffing -> cpudeadlinemissed
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001755 */
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001756 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001757 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001758 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1759 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001760 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1761 auto gpuFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001762 auto gpuFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1763 auto gpuFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001764 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001765 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001766 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1767 int64_t sfToken4 = mTokenManager->generateTokenForPredictions({112, 120, 120});
1768
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001769 // case 1 - cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001770 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001771 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
1772 auto displayFrame0 = getDisplayFrame(0);
1773 gpuFence1->signalForTest(36);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001774 presentFence1->signalForTest(52);
1775
1776 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001777 EXPECT_EQ(displayFrame0->getActuals().presentTime, 0);
1778
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001779 // case 2 - cpu time = 56 - 52 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001780 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001781 mFrameTimeline->setSfPresent(56, presentFence2, gpuFence2);
1782 auto displayFrame1 = getDisplayFrame(1);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001783 gpuFence2->signalForTest(76);
1784 presentFence2->signalForTest(90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001785
1786 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1787 // Fences have flushed for first displayFrame, so the present timestamps should be updated
1788 EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
1789 EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1790 EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Rachel Lee94917b32022-03-18 17:52:09 -07001791 EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001792
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001793 // case 3 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001794 mFrameTimeline->setSfWakeUp(sfToken3, 106, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001795 mFrameTimeline->setSfPresent(112, presentFence3, gpuFence3);
1796 auto displayFrame2 = getDisplayFrame(2);
1797 gpuFence3->signalForTest(116);
1798 presentFence3->signalForTest(120);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001799
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001800 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001801 // Fences have flushed for second displayFrame, so the present timestamps should be updated
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001802 EXPECT_EQ(displayFrame1->getActuals().presentTime, 90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001803 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1804 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1805 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001806
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001807 // case 4 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001808 mFrameTimeline->setSfWakeUp(sfToken4, 120, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001809 mFrameTimeline->setSfPresent(140, presentFence4, gpuFence4);
1810 auto displayFrame3 = getDisplayFrame(3);
1811 gpuFence4->signalForTest(156);
1812 presentFence4->signalForTest(180);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001813
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001814 EXPECT_EQ(displayFrame3->getActuals().presentTime, 0);
1815 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1816 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1817 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1818 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1819 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerStuffing);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001820
1821 addEmptyDisplayFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001822
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001823 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1824 EXPECT_EQ(displayFrame3->getActuals().presentTime, 180);
1825 EXPECT_EQ(displayFrame3->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1826 EXPECT_EQ(displayFrame3->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1827 EXPECT_EQ(displayFrame3->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001828}
1829
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001830TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001831 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001832 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001833 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1834 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001835 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1836 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08001837 FrameTimelineInfo ftInfo;
1838 ftInfo.vsyncId = surfaceFrameToken1;
1839 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001840 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001841 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1842 sLayerNameOne, sLayerNameOne,
1843 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001844 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001845 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001846 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1847 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001848 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001849 auto displayFrame1 = getDisplayFrame(0);
1850 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1851 presentFence1->signalForTest(30);
1852
1853 // Fences for the first frame haven't been flushed yet, so it should be 0
1854 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1855 auto actuals1 = presentedSurfaceFrame1.getActuals();
1856 EXPECT_EQ(actuals1.presentTime, 0);
1857
1858 // Trigger a flush by finalizing the next DisplayFrame
1859 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08001860 FrameTimelineInfo ftInfo2;
1861 ftInfo2.vsyncId = surfaceFrameToken2;
1862 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001863 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001864 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1865 sLayerNameOne, sLayerNameOne,
1866 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001867 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001868 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001869 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1870 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001871 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001872 auto displayFrame2 = getDisplayFrame(1);
1873 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1874
1875 // Fences for the first frame have flushed, so the present timestamps should be updated
1876 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1877 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1878 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1879 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1880
1881 actuals1 = presentedSurfaceFrame1.getActuals();
1882 EXPECT_EQ(actuals1.presentTime, 30);
1883 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1884 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1885 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1886
1887 // Fences for the second frame haven't been flushed yet, so it should be 0
1888 presentFence2->signalForTest(65);
1889 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1890 auto actuals2 = presentedSurfaceFrame2.getActuals();
1891 EXPECT_EQ(actuals2.presentTime, 0);
1892
Alec Mouri363faf02021-01-29 16:34:55 -08001893 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1894
1895 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001896 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
1897 sLayerNameOne, sGameMode,
1898 JankType::PredictionError, -3, 5,
1899 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08001900
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001901 addEmptyDisplayFrame();
1902
1903 // Fences for the second frame have flushed, so the present timestamps should be updated
1904 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1905 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1906 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1907 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1908
1909 actuals2 = presentedSurfaceFrame2.getActuals();
1910 EXPECT_EQ(actuals2.presentTime, 65);
1911 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1912 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1913 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1914}
1915
1916TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001917 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001918 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001919 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1920 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001921 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1922 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08001923 FrameTimelineInfo ftInfo;
1924 ftInfo.vsyncId = surfaceFrameToken1;
1925 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001926 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001927 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1928 sLayerNameOne, sLayerNameOne,
1929 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001930 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001931 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001932 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1933 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1934 mFrameTimeline->setSfPresent(26, presentFence1);
1935 auto displayFrame1 = getDisplayFrame(0);
1936 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1937 presentFence1->signalForTest(50);
1938
1939 // Fences for the first frame haven't been flushed yet, so it should be 0
1940 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1941 auto actuals1 = presentedSurfaceFrame1.getActuals();
1942 EXPECT_EQ(actuals1.presentTime, 0);
1943
1944 // Trigger a flush by finalizing the next DisplayFrame
1945 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08001946 FrameTimelineInfo ftInfo2;
1947 ftInfo2.vsyncId = surfaceFrameToken2;
1948 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001949 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001950 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1951 sLayerNameOne, sLayerNameOne,
1952 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001953 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001954 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001955 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1956 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001957 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001958 auto displayFrame2 = getDisplayFrame(1);
1959 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1960
1961 // Fences for the first frame have flushed, so the present timestamps should be updated
1962 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1963 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1964 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1965 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1966
1967 actuals1 = presentedSurfaceFrame1.getActuals();
1968 EXPECT_EQ(actuals1.presentTime, 50);
1969 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1970 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1971 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1972
1973 // Fences for the second frame haven't been flushed yet, so it should be 0
1974 presentFence2->signalForTest(86);
1975 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1976 auto actuals2 = presentedSurfaceFrame2.getActuals();
1977 EXPECT_EQ(actuals2.presentTime, 0);
1978
Alec Mouri363faf02021-01-29 16:34:55 -08001979 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1980
1981 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001982 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
1983 sLayerNameOne, sGameMode,
1984 JankType::PredictionError, -3, 5,
1985 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08001986
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001987 addEmptyDisplayFrame();
1988
1989 // Fences for the second frame have flushed, so the present timestamps should be updated
1990 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1991 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1992 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1993 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1994
1995 actuals2 = presentedSurfaceFrame2.getActuals();
1996 EXPECT_EQ(actuals2.presentTime, 86);
1997 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1998 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1999 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
2000}
2001
2002TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08002003 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08002004
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002005 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002006 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002007 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -08002008 FrameTimelineInfo ftInfo;
2009 ftInfo.vsyncId = surfaceFrameToken1;
2010 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002011 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002012 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2013 sLayerNameOne, sLayerNameOne,
2014 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002015 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002016 mFrameTimeline->setSfWakeUp(sfToken1, 42, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002017 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2018 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2019 mFrameTimeline->setSfPresent(46, presentFence1);
2020 auto displayFrame1 = getDisplayFrame(0);
2021 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2022 presentFence1->signalForTest(50);
2023
2024 // Fences for the first frame haven't been flushed yet, so it should be 0
2025 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2026 auto actuals1 = presentedSurfaceFrame1.getActuals();
2027 EXPECT_EQ(actuals1.presentTime, 0);
2028
2029 addEmptyDisplayFrame();
2030
2031 // Fences for the first frame have flushed, so the present timestamps should be updated
2032 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
2033 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2034 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2035 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2036
2037 actuals1 = presentedSurfaceFrame1.getActuals();
2038 EXPECT_EQ(actuals1.presentTime, 50);
2039 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2040 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2041 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
2042}
2043
2044TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002045 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as only
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002046 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002047 // jank to the SurfaceFrame along with AppDeadlineMissed.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002048
Alec Mouri363faf02021-01-29 16:34:55 -08002049 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002050 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002051 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
2052 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002053 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
2054 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
Huihong Luo3bdef862022-03-03 11:57:19 -08002055 FrameTimelineInfo ftInfo;
2056 ftInfo.vsyncId = surfaceFrameToken1;
2057 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002058 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002059 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2060 sLayerNameOne, sLayerNameOne,
2061 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002062 surfaceFrame1->setAcquireFenceTime(26);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002063 mFrameTimeline->setSfWakeUp(sfToken1, 32, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002064 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2065 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2066 mFrameTimeline->setSfPresent(36, presentFence1);
2067 auto displayFrame1 = getDisplayFrame(0);
2068 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2069 presentFence1->signalForTest(40);
2070
2071 // Fences for the first frame haven't been flushed yet, so it should be 0
2072 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2073 auto actuals1 = presentedSurfaceFrame1.getActuals();
2074 EXPECT_EQ(actuals1.presentTime, 0);
2075
2076 // Trigger a flush by finalizing the next DisplayFrame
2077 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002078 FrameTimelineInfo ftInfo2;
2079 ftInfo2.vsyncId = surfaceFrameToken2;
2080 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002081 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002082 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2083 sLayerNameOne, sLayerNameOne,
2084 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002085 surfaceFrame2->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002086 mFrameTimeline->setSfWakeUp(sfToken2, 43, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002087 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2088 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2089 mFrameTimeline->setSfPresent(56, presentFence2);
2090 auto displayFrame2 = getDisplayFrame(1);
2091 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2092
2093 // Fences for the first frame have flushed, so the present timestamps should be updated
2094 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
2095 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2096 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2097 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2098
2099 actuals1 = presentedSurfaceFrame1.getActuals();
2100 EXPECT_EQ(actuals1.presentTime, 40);
2101 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2102 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2103 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2104
2105 // Fences for the second frame haven't been flushed yet, so it should be 0
2106 presentFence2->signalForTest(60);
2107 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2108 auto actuals2 = presentedSurfaceFrame2.getActuals();
2109 EXPECT_EQ(actuals2.presentTime, 0);
2110
2111 addEmptyDisplayFrame();
2112
2113 // Fences for the second frame have flushed, so the present timestamps should be updated
2114 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
2115 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2116 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2117 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
2118
2119 actuals2 = presentedSurfaceFrame2.getActuals();
2120 EXPECT_EQ(actuals2.presentTime, 60);
2121 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2122 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002123 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2124 JankType::SurfaceFlingerCpuDeadlineMissed | JankType::AppDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002125}
2126
2127TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002128 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08002129 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002130 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2131 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2132 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2133
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002134 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2135 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Huihong Luo3bdef862022-03-03 11:57:19 -08002136 FrameTimelineInfo ftInfo;
2137 ftInfo.vsyncId = surfaceFrameToken1;
2138 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002139 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002140 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2141 sLayerNameOne, sLayerNameOne,
2142 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002143 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002144 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002145 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2146 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2147 mFrameTimeline->setSfPresent(56, presentFence1);
2148 auto displayFrame1 = getDisplayFrame(0);
2149 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2150 presentFence1->signalForTest(60);
2151
2152 // Fences for the first frame haven't been flushed yet, so it should be 0
2153 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2154 auto actuals1 = presentedSurfaceFrame1.getActuals();
2155 EXPECT_EQ(actuals1.presentTime, 0);
2156
2157 // Trigger a flush by finalizing the next DisplayFrame
2158 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002159 FrameTimelineInfo ftInfo2;
2160 ftInfo2.vsyncId = surfaceFrameToken2;
2161 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002162 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002163 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2164 sLayerNameOne, sLayerNameOne,
2165 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002166 surfaceFrame2->setAcquireFenceTime(84);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002167 mFrameTimeline->setSfWakeUp(sfToken2, 112, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002168 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2169 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2170 mFrameTimeline->setSfPresent(116, presentFence2);
2171 auto displayFrame2 = getDisplayFrame(1);
2172 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2173 presentFence2->signalForTest(120);
2174
2175 // Fences for the first frame have flushed, so the present timestamps should be updated
2176 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2177 actuals1 = presentedSurfaceFrame1.getActuals();
2178 EXPECT_EQ(actuals1.endTime, 50);
2179 EXPECT_EQ(actuals1.presentTime, 60);
2180
2181 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2182 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2183 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2184
2185 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2186 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2187 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2188
2189 // Fences for the second frame haven't been flushed yet, so it should be 0
2190 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2191 auto actuals2 = presentedSurfaceFrame2.getActuals();
2192 EXPECT_EQ(actuals2.presentTime, 0);
2193
2194 addEmptyDisplayFrame();
2195
2196 // Fences for the second frame have flushed, so the present timestamps should be updated
2197 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
2198 actuals2 = presentedSurfaceFrame2.getActuals();
2199 EXPECT_EQ(actuals2.presentTime, 120);
2200
2201 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2202 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2203 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
2204
2205 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2206 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2207 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2208 JankType::AppDeadlineMissed | JankType::BufferStuffing);
2209}
Alec Mouriadebf5c2021-01-05 12:57:36 -08002210
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002211TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
2212 // Layer specific increment
2213 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
2214 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2215 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2216 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2217
2218 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2219 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -08002220 FrameTimelineInfo ftInfo;
2221 ftInfo.vsyncId = surfaceFrameToken1;
2222 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002223 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002224 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2225 sLayerNameOne, sLayerNameOne,
2226 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002227 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002228 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002229 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2230 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2231 mFrameTimeline->setSfPresent(56, presentFence1);
2232 auto displayFrame1 = getDisplayFrame(0);
2233 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2234 presentFence1->signalForTest(60);
2235
2236 // Fences for the first frame haven't been flushed yet, so it should be 0
2237 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2238 auto actuals1 = presentedSurfaceFrame1.getActuals();
2239 EXPECT_EQ(actuals1.presentTime, 0);
2240
2241 // Trigger a flush by finalizing the next DisplayFrame
2242 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002243 FrameTimelineInfo ftInfo2;
2244 ftInfo2.vsyncId = surfaceFrameToken2;
2245 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002246 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002247 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2248 sLayerNameOne, sLayerNameOne,
2249 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002250 surfaceFrame2->setAcquireFenceTime(80);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002251 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002252 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
2253 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2254 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2255 mFrameTimeline->setSfPresent(86, presentFence2);
2256 auto displayFrame2 = getDisplayFrame(1);
2257 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2258 presentFence2->signalForTest(90);
2259
2260 // Fences for the first frame have flushed, so the present timestamps should be updated
2261 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2262 actuals1 = presentedSurfaceFrame1.getActuals();
2263 EXPECT_EQ(actuals1.endTime, 50);
2264 EXPECT_EQ(actuals1.presentTime, 60);
2265
2266 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2267 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2268 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2269
2270 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2271 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2272 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2273
2274 // Fences for the second frame haven't been flushed yet, so it should be 0
2275 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2276 auto actuals2 = presentedSurfaceFrame2.getActuals();
2277 EXPECT_EQ(actuals2.presentTime, 0);
2278
2279 addEmptyDisplayFrame();
2280
2281 // Fences for the second frame have flushed, so the present timestamps should be updated
2282 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2283 actuals2 = presentedSurfaceFrame2.getActuals();
2284 EXPECT_EQ(actuals2.presentTime, 90);
2285
2286 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2287 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2288 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
2289
2290 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2291 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2292 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
2293}
2294
Rachel Lee94917b32022-03-18 17:52:09 -07002295TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent_GpuAndCpuMiss) {
2296 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2297 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2298 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2299 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2300 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2301
2302 // Case 1: cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002303 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Rachel Lee94917b32022-03-18 17:52:09 -07002304 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
2305 auto displayFrame = getDisplayFrame(0);
2306 gpuFence1->signalForTest(36);
2307 presentFence1->signalForTest(52);
2308
2309 // Fences haven't been flushed yet, so it should be 0
2310 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
2311
2312 addEmptyDisplayFrame();
2313 displayFrame = getDisplayFrame(0);
2314
2315 // Fences have flushed, so the present timestamps should be updated
2316 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
2317 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2318 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2319 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
2320
2321 // Case 2: No GPU fence so it will not use GPU composition.
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002322 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Rachel Lee94917b32022-03-18 17:52:09 -07002323 mFrameTimeline->setSfPresent(66, presentFence2);
2324 auto displayFrame2 = getDisplayFrame(2); // 2 because of previous empty frame
2325 presentFence2->signalForTest(90);
2326
2327 // Fences for the frame haven't been flushed yet, so it should be 0
2328 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2329
2330 addEmptyDisplayFrame();
2331
2332 // Fences have flushed, so the present timestamps should be updated
2333 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2334 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2335 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2336 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
2337}
2338
Ady Abrahamfcb16862022-10-10 14:35:21 -07002339TEST_F(FrameTimelineTest, jankClassification_presentFenceError) {
2340 auto erroneousPresentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2341 auto erroneousPresentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2342 auto validPresentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2343 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2344 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2345 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({72, 80, 80});
2346
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002347 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002348 mFrameTimeline->setSfPresent(26, erroneousPresentFence1);
2349
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002350 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002351 mFrameTimeline->setSfPresent(60, erroneousPresentFence2);
2352
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002353 mFrameTimeline->setSfWakeUp(sfToken3, 72, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002354 mFrameTimeline->setSfPresent(80, validPresentFence);
2355
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002356 erroneousPresentFence2->signalForTest(2);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002357 validPresentFence->signalForTest(80);
2358
2359 addEmptyDisplayFrame();
2360
2361 {
2362 auto displayFrame = getDisplayFrame(0);
2363 EXPECT_EQ(displayFrame->getActuals().presentTime, 26);
2364 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2365 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002366 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002367 }
2368 {
2369 auto displayFrame = getDisplayFrame(1);
2370 EXPECT_EQ(displayFrame->getActuals().presentTime, 60);
2371 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2372 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002373 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002374 }
2375 {
2376 auto displayFrame = getDisplayFrame(2);
2377 EXPECT_EQ(displayFrame->getActuals().presentTime, 80);
2378 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2379 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2380 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
2381 }
2382}
2383
Alec Mouriadebf5c2021-01-05 12:57:36 -08002384TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
2385 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
2386}
2387
2388TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002389 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002390
2391 auto surfaceFrame1 =
2392 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002393 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002394 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002395 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2396 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2397 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2398 presentFence1->signalForTest(oneHundredMs);
2399 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2400
2401 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2402}
2403
2404TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002405 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2406 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002407 auto surfaceFrame1 =
2408 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002409 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002410 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002411 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2412 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2413 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2414 presentFence1->signalForTest(oneHundredMs);
2415 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2416
2417 auto surfaceFrame2 =
2418 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002419 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002420 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002421 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2422 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2423 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2424 presentFence2->signalForTest(twoHundredMs);
2425 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2426
2427 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
2428}
2429
2430TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002431 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2432 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002433 auto surfaceFrame1 =
2434 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002435 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002436 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002437 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2438 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2439 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2440 presentFence1->signalForTest(oneHundredMs);
2441 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2442
2443 auto surfaceFrame2 =
2444 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002445 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002446 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002447 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2448 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2449 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2450 presentFence2->signalForTest(twoHundredMs);
2451 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2452
2453 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
2454}
2455
2456TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002457 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2458 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002459 auto surfaceFrame1 =
2460 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002461 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002462 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002463 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2464 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2465 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2466 presentFence1->signalForTest(oneHundredMs);
2467 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2468
2469 auto surfaceFrame2 =
2470 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002471 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002472 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002473 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2474 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2475 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2476 presentFence2->signalForTest(twoHundredMs);
2477 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2478
2479 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2480}
2481
2482TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002483 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2484 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2485 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2486 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2487 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002488 auto surfaceFrame1 =
2489 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002490 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002491 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002492 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2493 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2494 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2495 presentFence1->signalForTest(oneHundredMs);
2496 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2497
2498 auto surfaceFrame2 =
2499 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002500 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002501 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002502 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2503 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2504 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2505 presentFence2->signalForTest(twoHundredMs);
2506 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2507
2508 auto surfaceFrame3 =
2509 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002510 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002511 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002512 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2513 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2514 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2515 presentFence3->signalForTest(threeHundredMs);
2516 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2517
2518 auto surfaceFrame4 =
2519 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002520 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002521 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002522 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2523 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2524 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2525 presentFence4->signalForTest(fiveHundredMs);
2526 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2527
2528 auto surfaceFrame5 =
2529 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002530 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002531 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002532 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2533 // Dropped frames will be excluded from fps computation
2534 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2535 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2536 presentFence5->signalForTest(sixHundredMs);
2537 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2538
2539 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2540}
2541
ramindaniea2bb822022-06-27 19:52:10 +00002542TEST_F(FrameTimelineTest, getMinTime) {
2543 // Use SurfaceFrame::getBaseTime to test the getMinTime.
2544 FrameTimelineInfo ftInfo;
2545
2546 // Valid prediction state test.
2547 ftInfo.vsyncId = 0L;
2548 mTokenManager->generateTokenForPredictions({10});
2549 auto surfaceFrame =
2550 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2551 sLayerNameOne, sLayerNameOne,
2552 /*isBuffer*/ true, sGameMode);
2553 ASSERT_EQ(surfaceFrame->getBaseTime(), 10);
2554
2555 // Test prediction state which is not valid.
2556 ftInfo.vsyncId = FrameTimelineInfo::INVALID_VSYNC_ID;
2557 surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2558 sLayerNameOne, sLayerNameOne,
2559 /*isBuffer*/ true, sGameMode);
2560 // Start time test.
2561 surfaceFrame->setActualStartTime(200);
2562 ASSERT_EQ(surfaceFrame->getBaseTime(), 200);
2563
2564 // End time test.
2565 surfaceFrame->setAcquireFenceTime(100);
2566 ASSERT_EQ(surfaceFrame->getBaseTime(), 100);
2567
2568 // Present time test.
2569 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2570 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2571 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2572 presentFence->signalForTest(std::chrono::nanoseconds(50ns).count());
2573 mFrameTimeline->setSfPresent(50, presentFence);
2574 ASSERT_EQ(surfaceFrame->getBaseTime(), 50);
2575}
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002576
2577TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingDisplayRate) {
2578 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2579 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2580 FrameTimelineInfo ftInfo;
2581 ftInfo.vsyncId = token1;
2582 ftInfo.inputEventId = sInputEventId;
2583 auto surfaceFrame =
2584 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2585 sLayerNameOne, sLayerNameOne,
2586 /*isBuffer*/ true, sGameMode);
2587
2588 mFrameTimeline->setSfWakeUp(token1, 20, RR_30, RR_11);
2589 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2590 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2591 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2592 mFrameTimeline->setSfPresent(50, presentFence1);
2593
2594 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 11);
2595}
2596
2597TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingAppFrameRate) {
2598 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2599 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2600 FrameTimelineInfo ftInfo;
2601 ftInfo.vsyncId = token1;
2602 ftInfo.inputEventId = sInputEventId;
2603 auto surfaceFrame =
2604 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2605 sLayerNameOne, sLayerNameOne,
2606 /*isBuffer*/ true, sGameMode);
2607 surfaceFrame->setRenderRate(RR_30);
2608 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
2609 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2610 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2611 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2612 mFrameTimeline->setSfPresent(50, presentFence1);
2613
2614 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 30);
2615}
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002616} // namespace android::frametimeline