blob: 9be0fc38b30594cb7f05e01701bd02762bb96fbc [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>
Pascal Mütschardd56514e2024-05-24 17:37:13 +020018#include "BackgroundExecutor.h"
19#include "Jank/JankTracker.h"
Sally Qif5721252023-11-17 11:14:53 -080020#include "com_android_graphics_surfaceflinger_flags.h"
Alec Mouri9a29e672020-09-14 12:39:14 -070021#include "gmock/gmock-spec-builders.h"
22#include "mock/MockTimeStats.h"
Adithya Srinivasanf279e042020-08-17 14:56:27 -070023#undef LOG_TAG
24#define LOG_TAG "LibSurfaceFlingerUnittests"
25
26#include <FrameTimeline/FrameTimeline.h>
27#include <gtest/gtest.h>
28#include <log/log.h>
Adithya Srinivasan01189672020-10-20 14:23:05 -070029#include <perfetto/trace/trace.pb.h>
Adithya Srinivasanf279e042020-08-17 14:56:27 -070030#include <cinttypes>
31
32using namespace std::chrono_literals;
Alec Mouri363faf02021-01-29 16:34:55 -080033using testing::_;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -080034using testing::AtLeast;
Alec Mouri9a29e672020-09-14 12:39:14 -070035using testing::Contains;
Adithya Srinivasan01189672020-10-20 14:23:05 -070036using FrameTimelineEvent = perfetto::protos::FrameTimelineEvent;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000037using ProtoExpectedDisplayFrameStart =
38 perfetto::protos::FrameTimelineEvent_ExpectedDisplayFrameStart;
39using ProtoExpectedSurfaceFrameStart =
40 perfetto::protos::FrameTimelineEvent_ExpectedSurfaceFrameStart;
41using ProtoActualDisplayFrameStart = perfetto::protos::FrameTimelineEvent_ActualDisplayFrameStart;
42using ProtoActualSurfaceFrameStart = perfetto::protos::FrameTimelineEvent_ActualSurfaceFrameStart;
43using ProtoFrameEnd = perfetto::protos::FrameTimelineEvent_FrameEnd;
Adithya Srinivasan01189672020-10-20 14:23:05 -070044using ProtoPresentType = perfetto::protos::FrameTimelineEvent_PresentType;
45using ProtoJankType = perfetto::protos::FrameTimelineEvent_JankType;
Ying Wei96eb5352023-11-21 17:37:21 +000046using ProtoJankSeverityType = perfetto::protos::FrameTimelineEvent_JankSeverityType;
Adithya Srinivasan78e58af2021-02-25 00:08:08 +000047using ProtoPredictionType = perfetto::protos::FrameTimelineEvent_PredictionType;
Alec Mouri9a29e672020-09-14 12:39:14 -070048
Adithya Srinivasanf279e042020-08-17 14:56:27 -070049namespace android::frametimeline {
50
Ady Abraham57a8ab42023-01-26 15:28:19 -080051static const std::string sLayerNameOne = "layer1";
52static const std::string sLayerNameTwo = "layer2";
53
54constexpr const uid_t sUidOne = 0;
55constexpr pid_t sPidOne = 10;
56constexpr pid_t sPidTwo = 20;
57constexpr int32_t sInputEventId = 5;
58constexpr int32_t sLayerIdOne = 1;
59constexpr int32_t sLayerIdTwo = 2;
60constexpr GameMode sGameMode = GameMode::Unsupported;
Pascal Muetschardac7bcd92023-10-03 15:05:36 +020061constexpr Fps RR_11 = Fps::fromPeriodNsecs(11);
62constexpr Fps RR_30 = Fps::fromPeriodNsecs(30);
Ady Abraham57a8ab42023-01-26 15:28:19 -080063
Adithya Srinivasanf279e042020-08-17 14:56:27 -070064class FrameTimelineTest : public testing::Test {
65public:
66 FrameTimelineTest() {
67 const ::testing::TestInfo* const test_info =
68 ::testing::UnitTest::GetInstance()->current_test_info();
69 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
70 }
71
72 ~FrameTimelineTest() {
73 const ::testing::TestInfo* const test_info =
74 ::testing::UnitTest::GetInstance()->current_test_info();
75 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
76 }
77
Adithya Srinivasan01189672020-10-20 14:23:05 -070078 static void SetUpTestSuite() {
79 // Need to initialize tracing in process for testing, and only once per test suite.
80 perfetto::TracingInitArgs args;
81 args.backends = perfetto::kInProcessBackend;
82 perfetto::Tracing::Initialize(args);
83 }
84
Adithya Srinivasanf279e042020-08-17 14:56:27 -070085 void SetUp() override {
Ady Abraham57f8e182022-03-08 15:54:33 -080086 constexpr bool kUseBootTimeClock = true;
Alec Mouri9a29e672020-09-14 12:39:14 -070087 mTimeStats = std::make_shared<mock::TimeStats>();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000088 mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats, kSurfaceFlingerPid,
Ady Abraham57f8e182022-03-08 15:54:33 -080089 kTestThresholds, !kUseBootTimeClock);
Adithya Srinivasan01189672020-10-20 14:23:05 -070090 mFrameTimeline->registerDataSource();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070091 mTokenManager = &mFrameTimeline->mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000092 mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
Adithya Srinivasan2d736322020-10-01 16:53:48 -070093 maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +000094 maxTokens = mTokenManager->kMaxTokens;
Pascal Mütschardd56514e2024-05-24 17:37:13 +020095
96 JankTracker::clearAndStartCollectingAllJankDataForTesting();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070097 }
98
Pascal Mütschardd56514e2024-05-24 17:37:13 +020099 void TearDown() override { JankTracker::clearAndStopCollectingAllJankDataForTesting(); }
100
Adithya Srinivasan01189672020-10-20 14:23:05 -0700101 // Each tracing session can be used for a single block of Start -> Stop.
102 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
103 perfetto::TraceConfig cfg;
104 cfg.set_duration_ms(500);
105 cfg.add_buffers()->set_size_kb(1024);
106 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
107 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
108
109 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
110 tracingSession->Setup(cfg);
111 return tracingSession;
112 }
113
114 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
115 perfetto::TracingSession* tracingSession) {
116 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
117 perfetto::protos::Trace trace;
118 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
119
120 std::vector<perfetto::protos::TracePacket> packets;
121 for (const auto& packet : trace.packet()) {
122 if (!packet.has_frame_timeline_event()) {
123 continue;
124 }
125 packets.emplace_back(packet);
126 }
127 return packets;
128 }
129
Ady Abraham57a8ab42023-01-26 15:28:19 -0800130 void addEmptySurfaceFrame() {
131 auto surfaceFrame =
132 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
133 sLayerNameOne, sLayerNameOne,
134 /*isBuffer*/ false, sGameMode);
135 mFrameTimeline->addSurfaceFrame(std::move(surfaceFrame));
136 }
137
Adithya Srinivasan01189672020-10-20 14:23:05 -0700138 void addEmptyDisplayFrame() {
139 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000140 // Trigger a flushPresentFence by calling setSfPresent for the next frame
Adithya Srinivasan01189672020-10-20 14:23:05 -0700141 mFrameTimeline->setSfPresent(2500, presentFence1);
142 }
143
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000144 void flushTokens() {
145 for (size_t i = 0; i < maxTokens; i++) {
146 mTokenManager->generateTokenForPredictions({});
147 }
148 EXPECT_EQ(getPredictions().size(), maxTokens);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700149 }
150
151 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
152 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800153 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
154 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700155 }
156
157 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
158 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
159 return mFrameTimeline->mDisplayFrames[idx];
160 }
161
162 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
163 return a.startTime == b.startTime && a.endTime == b.endTime &&
164 a.presentTime == b.presentTime;
165 }
166
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000167 const std::map<int64_t, TimelineItem>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700168 return mTokenManager->mPredictions;
169 }
170
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000171 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700172 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
173 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
174 }
175
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000176 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
177
178 void flushTrace() {
179 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
180 FrameTimelineDataSource::Trace(
181 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
182 }
183
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200184 std::vector<gui::JankData> getLayerOneJankData() {
185 BackgroundExecutor::getLowPriorityInstance().flushQueue();
186 return JankTracker::getCollectedJankDataForTesting(sLayerIdOne);
187 }
188
189 std::vector<gui::JankData> getLayerTwoJankData() {
190 BackgroundExecutor::getLowPriorityInstance().flushQueue();
191 return JankTracker::getCollectedJankDataForTesting(sLayerIdTwo);
192 }
193
Alec Mouri9a29e672020-09-14 12:39:14 -0700194 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700195 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
196 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000197 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700198 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700199 uint32_t* maxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000200 size_t maxTokens;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000201 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasanead17162021-02-18 02:17:37 +0000202 static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan54996e22021-06-25 22:26:45 +0000203 static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(0ns).count();
Adithya Srinivasanead17162021-02-18 02:17:37 +0000204 static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800205 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
206 kDeadlineThreshold,
207 kStartThreshold};
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700208};
209
210TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
211 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000212 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000213 flushTokens();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700214 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
215 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
216
217 // token1 should have expired
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700218 EXPECT_EQ(predictions.has_value(), false);
219
220 predictions = mTokenManager->getPredictionsForToken(token2);
221 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
222}
223
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700224TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800225 auto surfaceFrame1 =
226 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000227 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000228 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -0800229 auto surfaceFrame2 =
230 mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000231 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000232 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700233 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
234 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
235}
236
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700237TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800238 auto surfaceFrame =
239 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000240 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000241 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700242 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
243}
244
245TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
246 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000247 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -0800248 FrameTimelineInfo ftInfo;
249 ftInfo.vsyncId = token1;
250 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000251 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800252 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
253 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000254 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700255
256 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
257}
258
259TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
260 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800261 FrameTimelineInfo ftInfo;
262 ftInfo.vsyncId = token1;
263 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000264 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800265 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
266 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000267 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700268
269 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
270 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
271}
272
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000273TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
274 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
275 constexpr int32_t inputEventId = 1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800276 FrameTimelineInfo ftInfo;
277 ftInfo.vsyncId = token1;
278 ftInfo.inputEventId = inputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000279 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800280 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
281 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000282 /*isBuffer*/ true, sGameMode);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000283
284 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
285}
286
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700287TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
288 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700289 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800290 FrameTimelineInfo ftInfo;
291 ftInfo.vsyncId = token1;
292 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000293 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800294 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
295 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000296 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700297
298 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200299 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000300 surfaceFrame1->setDropTime(12);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800301 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
302 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700303 mFrameTimeline->setSfPresent(25, presentFence1);
304 presentFence1->signalForTest(30);
305
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000306 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700307
308 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
309 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000310 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
311 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700312 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
313}
314
315TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800316 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800317 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700318 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
319 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700320 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800321 FrameTimelineInfo ftInfo;
322 ftInfo.vsyncId = surfaceFrameToken1;
323 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700324 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800325 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
326 sLayerNameOne, sLayerNameOne,
327 /*isBuffer*/ true, sGameMode);
Alec Mouri9a29e672020-09-14 12:39:14 -0700328 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800329 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdTwo,
330 sLayerNameTwo, sLayerNameTwo,
331 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200332 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800333 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
334 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
335 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
336 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700337 mFrameTimeline->setSfPresent(26, presentFence1);
338 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800339 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
340 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700341 presentFence1->signalForTest(42);
342
343 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800344 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700345 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
346 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
347
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000348 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700349
350 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800351 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700352 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
353 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100354 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
Ying Wei96eb5352023-11-21 17:37:21 +0000355 EXPECT_NE(surfaceFrame1->getJankSeverityType(), std::nullopt);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100356 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Ying Wei96eb5352023-11-21 17:37:21 +0000357 EXPECT_NE(surfaceFrame2->getJankSeverityType(), std::nullopt);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200358
359 EXPECT_EQ(getLayerOneJankData().size(), 1u);
360 EXPECT_EQ(getLayerTwoJankData().size(), 1u);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700361}
362
Ady Abraham14beed72024-05-15 17:16:45 -0700363TEST_F(FrameTimelineTest, displayFrameSkippedComposition) {
364 // Layer specific increment
365 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(1);
366 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
367 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
368 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
369 FrameTimelineInfo ftInfo;
370 ftInfo.vsyncId = surfaceFrameToken1;
371 ftInfo.inputEventId = sInputEventId;
372 auto surfaceFrame1 =
373 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
374 sLayerNameOne, sLayerNameOne,
375 /*isBuffer*/ true, sGameMode);
376 auto surfaceFrame2 =
377 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdTwo,
378 sLayerNameTwo, sLayerNameTwo,
379 /*isBuffer*/ true, sGameMode);
380
381 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
382 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
383 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
384 mFrameTimeline->onCommitNotComposited();
385
386 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 30);
387 ASSERT_NE(surfaceFrame1->getJankType(), std::nullopt);
388 EXPECT_EQ(*surfaceFrame1->getJankType(), JankType::None);
389 ASSERT_NE(surfaceFrame1->getJankSeverityType(), std::nullopt);
390 EXPECT_EQ(*surfaceFrame1->getJankSeverityType(), JankSeverityType::None);
391
392 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
393 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
394 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
395 mFrameTimeline->setSfPresent(26, presentFence1);
396
397 auto displayFrame = getDisplayFrame(0);
398 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 0);
399 presentFence1->signalForTest(42);
400
401 // Fences haven't been flushed yet, so it should be 0
402 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
403 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
404
405 addEmptyDisplayFrame();
406
407 // Fences have flushed, so the present timestamps should be updated
408 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
409 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
410 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
411 EXPECT_NE(surfaceFrame2->getJankSeverityType(), std::nullopt);
412}
413
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700414TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
415 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
416 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800417 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800418 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800419 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700420 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700421 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
422 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
423 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
424 int64_t sfToken = mTokenManager->generateTokenForPredictions(
425 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800426 FrameTimelineInfo ftInfo;
427 ftInfo.vsyncId = surfaceFrameToken;
428 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700429 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800430 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000431 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000432 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200433 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800434 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
435 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700436 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
437 presentFence->signalForTest(32 + frameTimeFactor);
438 frameTimeFactor += 30;
439 }
440 auto displayFrame0 = getDisplayFrame(0);
441
442 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800443 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700444
445 // Add one more display frame
446 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
447 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
448 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
449 int64_t sfToken = mTokenManager->generateTokenForPredictions(
450 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800451 FrameTimelineInfo ftInfo;
452 ftInfo.vsyncId = surfaceFrameToken;
453 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700454 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800455 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
456 sLayerNameOne, sLayerNameOne,
457 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200458 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800459 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
460 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700461 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
462 presentFence->signalForTest(32 + frameTimeFactor);
463 displayFrame0 = getDisplayFrame(0);
464
465 // The window should have slided by 1 now and the previous 0th display frame
466 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800467 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200468
469 EXPECT_EQ(getLayerOneJankData().size(), *maxDisplayFrames);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700470}
471
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700472TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000473 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
474 "acquireFenceAfterQueue",
475 "acquireFenceAfterQueue",
476 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700477 surfaceFrame->setActualQueueTime(123);
478 surfaceFrame->setAcquireFenceTime(456);
479 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
480}
481
Vishnu Nairbd7d07e2024-07-08 13:37:11 -0700482TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceUnsignaled) {
483 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
484 "acquireFenceAfterQueue",
485 "acquireFenceAfterQueue",
486 /*isBuffer*/ true, sGameMode);
487 surfaceFrame->setActualQueueTime(123);
488 surfaceFrame->setAcquireFenceTime(Fence::SIGNAL_TIME_PENDING);
489 EXPECT_EQ(surfaceFrame->getActuals().endTime, 123);
490}
491
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700492TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000493 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
494 "acquireFenceAfterQueue",
495 "acquireFenceAfterQueue",
496 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700497 surfaceFrame->setActualQueueTime(456);
498 surfaceFrame->setAcquireFenceTime(123);
499 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
500}
501
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700502TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
503 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
504 presentFence->signalForTest(2);
505
506 // Size shouldn't exceed maxDisplayFrames - 64
507 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700508 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800509 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000510 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000511 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700512 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200513 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800514 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
515 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700516 mFrameTimeline->setSfPresent(27, presentFence);
517 }
518 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
519
520 // Increase the size to 256
521 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000522 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700523
524 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700525 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800526 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000527 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000528 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700529 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200530 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800531 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
532 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700533 mFrameTimeline->setSfPresent(27, presentFence);
534 }
535 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
536
537 // Shrink the size to 128
538 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000539 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700540
541 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700542 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800543 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000544 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000545 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700546 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200547 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800548 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
549 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700550 mFrameTimeline->setSfPresent(27, presentFence);
551 }
552 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
553}
Alec Mouri9a29e672020-09-14 12:39:14 -0700554
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000555TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200556 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000557
558 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
559 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
560 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800561 FrameTimelineInfo ftInfo;
562 ftInfo.vsyncId = surfaceFrameToken1;
563 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000564
565 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800566 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
567 sLayerNameOne, sLayerNameOne,
568 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200569 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000570 surfaceFrame1->setAcquireFenceTime(20);
571 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
572 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
573
574 mFrameTimeline->setSfPresent(59, presentFence1);
575 presentFence1->signalForTest(-1);
576 addEmptyDisplayFrame();
577
578 auto displayFrame0 = getDisplayFrame(0);
Ady Abrahamfcb16862022-10-10 14:35:21 -0700579 EXPECT_EQ(displayFrame0->getActuals().presentTime, 59);
Ady Abrahamb1e10d12023-03-13 15:23:54 -0700580 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +0000581 EXPECT_EQ(displayFrame0->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000582 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
583 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +0000584 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000585}
586
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800587// Tests related to TimeStats
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000588TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200589 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000590 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
591 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
592 int64_t surfaceFrameToken1 = -1;
593 int64_t sfToken1 = -1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800594 FrameTimelineInfo ftInfo;
595 ftInfo.vsyncId = surfaceFrameToken1;
596 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000597
598 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800599 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
600 sLayerNameOne, sLayerNameOne,
601 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200602 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000603 surfaceFrame1->setAcquireFenceTime(20);
604 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
605 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
606 presentFence1->signalForTest(70);
607
608 mFrameTimeline->setSfPresent(59, presentFence1);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200609
610 EXPECT_EQ(getLayerOneJankData().size(), 0u);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000611}
612
Alec Mouri9a29e672020-09-14 12:39:14 -0700613TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200614 Fps refreshRate = RR_11;
Alec Mouri9a29e672020-09-14 12:39:14 -0700615 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800616 incrementJankyFrames(
617 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000618 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000619 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800620 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700621 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000622 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
623 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800624 FrameTimelineInfo ftInfo;
625 ftInfo.vsyncId = surfaceFrameToken1;
626 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000627
Alec Mouri9a29e672020-09-14 12:39:14 -0700628 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800629 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
630 sLayerNameOne, sLayerNameOne,
631 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200632 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000633 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800634 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
635 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000636 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700637
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000638 mFrameTimeline->setSfPresent(62, presentFence1);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200639
640 auto jankData = getLayerOneJankData();
641 EXPECT_EQ(jankData.size(), 1u);
642 EXPECT_EQ(jankData[0].jankType, JankType::SurfaceFlingerCpuDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700643}
644
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000645TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfGpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200646 Fps refreshRate = RR_11;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000647 EXPECT_CALL(*mTimeStats,
648 incrementJankyFrames(
649 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000650 sLayerNameOne, sGameMode,
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000651 JankType::SurfaceFlingerGpuDeadlineMissed, 4, 10,
652 0}));
653 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
654 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
655 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
656 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800657 FrameTimelineInfo ftInfo;
658 ftInfo.vsyncId = surfaceFrameToken1;
659 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000660
661 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800662 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
663 sLayerNameOne, sLayerNameOne,
664 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200665 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000666 surfaceFrame1->setAcquireFenceTime(20);
667 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
668 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
669 gpuFence1->signalForTest(64);
670 presentFence1->signalForTest(70);
671
672 mFrameTimeline->setSfPresent(59, presentFence1, gpuFence1);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200673
674 auto jankData = getLayerOneJankData();
675 EXPECT_EQ(jankData.size(), 1u);
676 EXPECT_EQ(jankData[0].jankType, JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000677}
678
Alec Mouri9a29e672020-09-14 12:39:14 -0700679TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200680 Fps refreshRate = RR_30;
Alec Mouri9a29e672020-09-14 12:39:14 -0700681 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800682 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000683 sLayerNameOne, sGameMode,
684 JankType::DisplayHAL, -4, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800685
Alec Mouri9a29e672020-09-14 12:39:14 -0700686 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000687 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
688 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800689 FrameTimelineInfo ftInfo;
690 ftInfo.vsyncId = surfaceFrameToken1;
691 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000692
Alec Mouri9a29e672020-09-14 12:39:14 -0700693 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800694 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
695 sLayerNameOne, sLayerNameOne,
696 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200697 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800698 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000699 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800700 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000701 presentFence1->signalForTest(90);
702 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800703 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +0000704 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200705
706 auto jankData = getLayerOneJankData();
707 EXPECT_EQ(jankData.size(), 1u);
708 EXPECT_EQ(jankData[0].jankType, JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700709}
710
711TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700712 Fps refreshRate = 11_Hz;
Alec Mouri9a29e672020-09-14 12:39:14 -0700713 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000714 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000715 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000716 JankType::AppDeadlineMissed, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000717 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700718 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000719 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
720 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800721 FrameTimelineInfo ftInfo;
722 ftInfo.vsyncId = surfaceFrameToken1;
723 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000724
Alec Mouri9a29e672020-09-14 12:39:14 -0700725 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800726 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
727 sLayerNameOne, sLayerNameOne,
728 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000729 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200730 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700731
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800732 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
733 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000734 presentFence1->signalForTest(90);
735 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100736
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800737 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000738 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Partial);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200739
740 auto jankData = getLayerOneJankData();
741 EXPECT_EQ(jankData.size(), 1u);
742 EXPECT_EQ(jankData[0].jankType, JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700743}
744
Adithya Srinivasanead17162021-02-18 02:17:37 +0000745TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000746 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000747 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000748 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000749 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000750 JankType::SurfaceFlingerScheduling,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000751 -4, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000752 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000753 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
754 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800755 FrameTimelineInfo ftInfo;
756 ftInfo.vsyncId = surfaceFrameToken1;
757 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000758
Adithya Srinivasanead17162021-02-18 02:17:37 +0000759 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800760 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
761 sLayerNameOne, sLayerNameOne,
762 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000763 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200764 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000765
766 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
767 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000768 presentFence1->signalForTest(60);
769 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000770
771 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +0000772 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200773
774 auto jankData = getLayerOneJankData();
775 EXPECT_EQ(jankData.size(), 1u);
776 EXPECT_EQ(jankData[0].jankType, JankType::SurfaceFlingerScheduling);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000777}
778
779TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000780 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000781 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000782 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000783 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000784 JankType::PredictionError, -4, 5,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000785 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000786 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000787 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
788 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800789 FrameTimelineInfo ftInfo;
790 ftInfo.vsyncId = surfaceFrameToken1;
791 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000792
Adithya Srinivasanead17162021-02-18 02:17:37 +0000793 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800794 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
795 sLayerNameOne, sLayerNameOne,
796 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000797 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200798 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000799
800 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
801 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000802 presentFence1->signalForTest(65);
803 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000804
805 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +0000806 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Partial);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200807
808 auto jankData = getLayerOneJankData();
809 EXPECT_EQ(jankData.size(), 1u);
810 EXPECT_EQ(jankData[0].jankType, JankType::PredictionError);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000811}
812
813TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000814 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000815 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000816 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000817 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000818 JankType::BufferStuffing, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000819 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000820 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000821 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
822 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800823 FrameTimelineInfo ftInfo;
824 ftInfo.vsyncId = surfaceFrameToken1;
825 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000826
Adithya Srinivasanead17162021-02-18 02:17:37 +0000827 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800828 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
829 sLayerNameOne, sLayerNameOne,
830 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000831 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200832 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000833
834 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000835 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000836 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000837 presentFence1->signalForTest(90);
838 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000839
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000840 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +0000841 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200842
843 auto jankData = getLayerOneJankData();
844 EXPECT_EQ(jankData.size(), 1u);
845 EXPECT_EQ(jankData[0].jankType, JankType::BufferStuffing);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000846}
847
Alec Mouri363faf02021-01-29 16:34:55 -0800848TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200849 Fps refreshRate = RR_11;
850 Fps renderRate = RR_30;
Alec Mouri363faf02021-01-29 16:34:55 -0800851 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000852 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne,
853 sLayerNameOne, sGameMode,
854 JankType::AppDeadlineMissed, -4, 0,
855 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800856 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000857 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
858 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800859 FrameTimelineInfo ftInfo;
860 ftInfo.vsyncId = surfaceFrameToken1;
861 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000862
Alec Mouri363faf02021-01-29 16:34:55 -0800863 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800864 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
865 sLayerNameOne, sLayerNameOne,
866 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000867 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200868 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800869
870 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
871 surfaceFrame1->setRenderRate(renderRate);
872 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000873 presentFence1->signalForTest(90);
874 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800875
876 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000877 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200878
879 auto jankData = getLayerOneJankData();
880 EXPECT_EQ(jankData.size(), 1u);
881 EXPECT_EQ(jankData[0].jankType, JankType::AppDeadlineMissed);
Alec Mouri363faf02021-01-29 16:34:55 -0800882}
883
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000884TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200885 Fps refreshRate = RR_11;
886 Fps renderRate = RR_30;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000887
888 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000889 incrementJankyFrames(
890 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000891 sGameMode,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000892 JankType::Unknown | JankType::AppDeadlineMissed,
Adithya Srinivasande272452021-04-10 00:21:00 +0000893 0, 0, 25}));
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000894 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
895 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
896 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800897 FrameTimelineInfo ftInfo;
898 ftInfo.vsyncId = surfaceFrameToken1;
899 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000900
901 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800902 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
903 sLayerNameOne, sLayerNameOne,
904 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000905 surfaceFrame1->setAcquireFenceTime(45);
906 // Trigger a prediction expiry
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000907 flushTokens();
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200908 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000909
910 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
911 surfaceFrame1->setRenderRate(renderRate);
912 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
913 presentFence1->signalForTest(90);
914 mFrameTimeline->setSfPresent(86, presentFence1);
915
916 auto displayFrame = getDisplayFrame(0);
917 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +0000918 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000919 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
920 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
921 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
922
923 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000924 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000925 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200926
927 auto jankData = getLayerOneJankData();
928 EXPECT_EQ(jankData.size(), 1u);
929 EXPECT_EQ(jankData[0].jankType, JankType::Unknown | JankType::AppDeadlineMissed);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000930}
931
Adithya Srinivasan01189672020-10-20 14:23:05 -0700932/*
933 * Tracing Tests
934 *
935 * Trace packets are flushed all the way only when the next packet is traced.
936 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
937 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
938 * will have additional empty frames created for this reason.
939 */
940TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
941 auto tracingSession = getTracingSessionForTest();
942 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700943 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800944 FrameTimelineInfo ftInfo;
945 ftInfo.vsyncId = token1;
946 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000947 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800948 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
949 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000950 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700951
952 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200953 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800954 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
955 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700956 mFrameTimeline->setSfPresent(25, presentFence1);
957 presentFence1->signalForTest(30);
958
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000959 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700960
961 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000962 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700963}
964
965TEST_F(FrameTimelineTest, tracing_sanityTest) {
966 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800967 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800968 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700969 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700970
971 tracingSession->StartBlocking();
972 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
973 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800974 FrameTimelineInfo ftInfo;
975 ftInfo.vsyncId = token1;
976 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000977 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800978 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
979 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000980 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700981
982 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200983 mFrameTimeline->setSfWakeUp(token2, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800984 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
985 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700986 mFrameTimeline->setSfPresent(25, presentFence1);
987 presentFence1->signalForTest(30);
988
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000989 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000990 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700991 tracingSession->StopBlocking();
992
993 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000994 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000995 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700996}
997
998TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
999 auto tracingSession = getTracingSessionForTest();
1000 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001001
1002 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001003
1004 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001005 mFrameTimeline->setSfWakeUp(-1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001006 mFrameTimeline->setSfPresent(25, presentFence1);
1007 presentFence1->signalForTest(30);
1008
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001009 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001010 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001011 tracingSession->StopBlocking();
1012
1013 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001014 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001015}
1016
1017TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
1018 auto tracingSession = getTracingSessionForTest();
1019 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001020
1021 tracingSession->StartBlocking();
1022 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -08001023 auto surfaceFrame1 =
1024 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001025 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001026 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001027
1028 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001029 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001030 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1031 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001032 mFrameTimeline->setSfPresent(25, presentFence1);
1033 presentFence1->signalForTest(30);
1034
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001035 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001036 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001037 tracingSession->StopBlocking();
1038
1039 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001040 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
1041 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001042 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001043}
1044
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001045ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
1046 pid_t pid) {
1047 ProtoExpectedDisplayFrameStart proto;
1048 proto.set_cookie(cookie);
1049 proto.set_token(token);
1050 proto.set_pid(pid);
1051 return proto;
1052}
1053
1054ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
1055 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Ying Wei96eb5352023-11-21 17:37:21 +00001056 bool gpuComposition, ProtoJankType jankType, ProtoJankSeverityType jankSeverityType,
1057 ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001058 ProtoActualDisplayFrameStart proto;
1059 proto.set_cookie(cookie);
1060 proto.set_token(token);
1061 proto.set_pid(pid);
1062 proto.set_present_type(presentType);
1063 proto.set_on_time_finish(onTimeFinish);
1064 proto.set_gpu_composition(gpuComposition);
1065 proto.set_jank_type(jankType);
Ying Wei96eb5352023-11-21 17:37:21 +00001066 proto.set_jank_severity_type(jankSeverityType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001067 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001068 return proto;
1069}
1070
1071ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
1072 int64_t displayFrameToken,
1073 pid_t pid,
1074 std::string layerName) {
1075 ProtoExpectedSurfaceFrameStart proto;
1076 proto.set_cookie(cookie);
1077 proto.set_token(token);
1078 proto.set_display_frame_token(displayFrameToken);
1079 proto.set_pid(pid);
1080 proto.set_layer_name(layerName);
1081 return proto;
1082}
1083
1084ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
1085 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
1086 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Ying Wei96eb5352023-11-21 17:37:21 +00001087 ProtoJankType jankType, ProtoJankSeverityType jankSeverityType,
1088 ProtoPredictionType predictionType, bool isBuffer) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001089 ProtoActualSurfaceFrameStart proto;
1090 proto.set_cookie(cookie);
1091 proto.set_token(token);
1092 proto.set_display_frame_token(displayFrameToken);
1093 proto.set_pid(pid);
1094 proto.set_layer_name(layerName);
1095 proto.set_present_type(presentType);
1096 proto.set_on_time_finish(onTimeFinish);
1097 proto.set_gpu_composition(gpuComposition);
1098 proto.set_jank_type(jankType);
Ying Wei96eb5352023-11-21 17:37:21 +00001099 proto.set_jank_severity_type(jankSeverityType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001100 proto.set_prediction_type(predictionType);
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001101 proto.set_is_buffer(isBuffer);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001102 return proto;
1103}
1104
1105ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
1106 ProtoFrameEnd proto;
1107 proto.set_cookie(cookie);
1108 return proto;
1109}
1110
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001111void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
1112 const ProtoExpectedDisplayFrameStart& source) {
1113 ASSERT_TRUE(received.has_cookie());
1114 EXPECT_EQ(received.cookie(), source.cookie());
1115
Adithya Srinivasan01189672020-10-20 14:23:05 -07001116 ASSERT_TRUE(received.has_token());
1117 EXPECT_EQ(received.token(), source.token());
1118
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001119 ASSERT_TRUE(received.has_pid());
1120 EXPECT_EQ(received.pid(), source.pid());
1121}
1122
1123void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
1124 const ProtoActualDisplayFrameStart& source) {
1125 ASSERT_TRUE(received.has_cookie());
1126 EXPECT_EQ(received.cookie(), source.cookie());
1127
1128 ASSERT_TRUE(received.has_token());
1129 EXPECT_EQ(received.token(), source.token());
1130
1131 ASSERT_TRUE(received.has_pid());
1132 EXPECT_EQ(received.pid(), source.pid());
1133
Adithya Srinivasan01189672020-10-20 14:23:05 -07001134 ASSERT_TRUE(received.has_present_type());
1135 EXPECT_EQ(received.present_type(), source.present_type());
1136 ASSERT_TRUE(received.has_on_time_finish());
1137 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1138 ASSERT_TRUE(received.has_gpu_composition());
1139 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1140 ASSERT_TRUE(received.has_jank_type());
1141 EXPECT_EQ(received.jank_type(), source.jank_type());
Ying Wei96eb5352023-11-21 17:37:21 +00001142 ASSERT_TRUE(received.has_jank_severity_type());
1143 EXPECT_EQ(received.jank_severity_type(), source.jank_severity_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001144 ASSERT_TRUE(received.has_prediction_type());
1145 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001146}
1147
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001148void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
1149 const ProtoExpectedSurfaceFrameStart& source) {
1150 ASSERT_TRUE(received.has_cookie());
1151 EXPECT_EQ(received.cookie(), source.cookie());
1152
Adithya Srinivasan01189672020-10-20 14:23:05 -07001153 ASSERT_TRUE(received.has_token());
1154 EXPECT_EQ(received.token(), source.token());
1155
1156 ASSERT_TRUE(received.has_display_frame_token());
1157 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1158
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001159 ASSERT_TRUE(received.has_pid());
1160 EXPECT_EQ(received.pid(), source.pid());
1161
1162 ASSERT_TRUE(received.has_layer_name());
1163 EXPECT_EQ(received.layer_name(), source.layer_name());
1164}
1165
1166void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
1167 const ProtoActualSurfaceFrameStart& source) {
1168 ASSERT_TRUE(received.has_cookie());
1169 EXPECT_EQ(received.cookie(), source.cookie());
1170
1171 ASSERT_TRUE(received.has_token());
1172 EXPECT_EQ(received.token(), source.token());
1173
1174 ASSERT_TRUE(received.has_display_frame_token());
1175 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1176
1177 ASSERT_TRUE(received.has_pid());
1178 EXPECT_EQ(received.pid(), source.pid());
1179
1180 ASSERT_TRUE(received.has_layer_name());
1181 EXPECT_EQ(received.layer_name(), source.layer_name());
1182
Adithya Srinivasan01189672020-10-20 14:23:05 -07001183 ASSERT_TRUE(received.has_present_type());
1184 EXPECT_EQ(received.present_type(), source.present_type());
1185 ASSERT_TRUE(received.has_on_time_finish());
1186 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1187 ASSERT_TRUE(received.has_gpu_composition());
1188 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1189 ASSERT_TRUE(received.has_jank_type());
1190 EXPECT_EQ(received.jank_type(), source.jank_type());
Ying Wei96eb5352023-11-21 17:37:21 +00001191 ASSERT_TRUE(received.has_jank_severity_type());
1192 EXPECT_EQ(received.jank_severity_type(), source.jank_severity_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001193 ASSERT_TRUE(received.has_prediction_type());
1194 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001195 ASSERT_TRUE(received.has_is_buffer());
1196 EXPECT_EQ(received.is_buffer(), source.is_buffer());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001197}
Adithya Srinivasan01189672020-10-20 14:23:05 -07001198
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001199void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
1200 ASSERT_TRUE(received.has_cookie());
1201 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001202}
1203
Sally Qi2269a692024-05-17 18:02:28 -07001204TEST_F(FrameTimelineTest, traceDisplayFrameNoSkipped) {
1205 // setup 2 display frames
1206 // DF 1: [22, 30] -> [0, 11]
1207 // DF 2: [82, 90] -> SF [5, 16]
1208 auto tracingSession = getTracingSessionForTest();
1209 tracingSession->StartBlocking();
1210 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1211 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 100});
1212 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({0, 11, 25});
1213 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1214 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1215
1216 int64_t traceCookie = snoopCurrentTraceCookie();
1217
1218 // set up 1st display frame
1219 FrameTimelineInfo ftInfo1;
1220 ftInfo1.vsyncId = surfaceFrameToken1;
1221 ftInfo1.inputEventId = sInputEventId;
1222 auto surfaceFrame1 =
1223 mFrameTimeline->createSurfaceFrameForToken(ftInfo1, sPidOne, sUidOne, sLayerIdOne,
1224 sLayerNameOne, sLayerNameOne,
1225 /*isBuffer*/ true, sGameMode);
1226 surfaceFrame1->setAcquireFenceTime(11);
1227 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_30);
1228 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1229 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1230 mFrameTimeline->setSfPresent(30, presentFence1);
1231 presentFence1->signalForTest(40);
1232
1233 // Trigger a flush by finalizing the next DisplayFrame
1234 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1235 FrameTimelineInfo ftInfo2;
1236 ftInfo2.vsyncId = surfaceFrameToken2;
1237 ftInfo2.inputEventId = sInputEventId;
1238 auto surfaceFrame2 =
1239 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1240 sLayerNameOne, sLayerNameOne,
1241 /*isBuffer*/ true, sGameMode);
1242
1243 // set up 2nd display frame
1244 surfaceFrame2->setAcquireFenceTime(16);
1245 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_11, RR_30);
1246 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1247 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1248 mFrameTimeline->setSfPresent(90, presentFence2);
1249 presentFence2->signalForTest(100);
1250
1251 // the token of skipped Display Frame
1252 auto protoSkippedActualDisplayFrameStart =
1253 createProtoActualDisplayFrameStart(traceCookie + 9, 0, kSurfaceFlingerPid,
1254 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1255 FrameTimelineEvent::JANK_DROPPED,
1256 FrameTimelineEvent::SEVERITY_NONE,
1257 FrameTimelineEvent::PREDICTION_VALID);
1258 auto protoSkippedActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 9);
1259
1260 // Trigger a flush by finalizing the next DisplayFrame
1261 addEmptyDisplayFrame();
1262 flushTrace();
1263 tracingSession->StopBlocking();
1264
1265 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1266 // 8 Valid Display Frames + 8 Valid Surface Frames + no Skipped Display Frames
1267 EXPECT_EQ(packets.size(), 16u);
1268}
1269
Sally Qiaa107742023-09-29 14:53:14 -07001270TEST_F(FrameTimelineTest, traceDisplayFrameSkipped) {
Sally Qif5721252023-11-17 11:14:53 -08001271 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::add_sf_skipped_frames_to_trace,
1272 true);
1273
Sally Qiaa107742023-09-29 14:53:14 -07001274 // setup 2 display frames
1275 // DF 1: [22,40] -> [5, 40]
1276 // DF : [36, 70] (Skipped one, added by the trace)
1277 // DF 2: [82, 100] -> SF [25, 70]
1278 auto tracingSession = getTracingSessionForTest();
1279 tracingSession->StartBlocking();
1280 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1281 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 100});
1282 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1283 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1284 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1285
1286 int64_t traceCookie = snoopCurrentTraceCookie();
1287
1288 // set up 1st display frame
1289 FrameTimelineInfo ftInfo1;
1290 ftInfo1.vsyncId = surfaceFrameToken1;
1291 ftInfo1.inputEventId = sInputEventId;
1292 auto surfaceFrame1 =
1293 mFrameTimeline->createSurfaceFrameForToken(ftInfo1, sPidOne, sUidOne, sLayerIdOne,
1294 sLayerNameOne, sLayerNameOne,
1295 /*isBuffer*/ true, sGameMode);
1296 surfaceFrame1->setAcquireFenceTime(16);
1297 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_30);
1298 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1299 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1300 mFrameTimeline->setSfPresent(30, presentFence1);
1301 presentFence1->signalForTest(40);
1302
1303 // Trigger a flush by finalizing the next DisplayFrame
1304 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1305 FrameTimelineInfo ftInfo2;
1306 ftInfo2.vsyncId = surfaceFrameToken2;
1307 ftInfo2.inputEventId = sInputEventId;
1308 auto surfaceFrame2 =
1309 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1310 sLayerNameOne, sLayerNameOne,
1311 /*isBuffer*/ true, sGameMode);
1312
1313 // set up 2nd display frame
1314 surfaceFrame2->setAcquireFenceTime(36);
1315 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_11, RR_30);
1316 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1317 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1318 mFrameTimeline->setSfPresent(90, presentFence2);
1319 presentFence2->signalForTest(100);
1320
1321 // the token of skipped Display Frame
1322 auto protoSkippedActualDisplayFrameStart =
1323 createProtoActualDisplayFrameStart(traceCookie + 9, 0, kSurfaceFlingerPid,
1324 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1325 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001326 FrameTimelineEvent::SEVERITY_NONE,
Sally Qiaa107742023-09-29 14:53:14 -07001327 FrameTimelineEvent::PREDICTION_VALID);
1328 auto protoSkippedActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 9);
1329
1330 // Trigger a flush by finalizing the next DisplayFrame
1331 addEmptyDisplayFrame();
1332 flushTrace();
1333 tracingSession->StopBlocking();
1334
1335 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1336 // 8 Valid Display Frames + 8 Valid Surface Frames + 2 Skipped Display Frames
1337 EXPECT_EQ(packets.size(), 18u);
1338
1339 // Packet - 16: Actual skipped Display Frame Start
1340 // the timestamp should be equal to the 2nd expected surface frame's end time
1341 const auto& packet16 = packets[16];
1342 ASSERT_TRUE(packet16.has_timestamp());
1343 EXPECT_EQ(packet16.timestamp(), 36u);
1344 ASSERT_TRUE(packet16.has_frame_timeline_event());
1345
1346 const auto& event16 = packet16.frame_timeline_event();
1347 const auto& actualSkippedDisplayFrameStart = event16.actual_display_frame_start();
1348 validateTraceEvent(actualSkippedDisplayFrameStart, protoSkippedActualDisplayFrameStart);
1349
1350 // Packet - 17: Actual skipped Display Frame End
1351 // the timestamp should be equal to the 2nd expected surface frame's present time
1352 const auto& packet17 = packets[17];
1353 ASSERT_TRUE(packet17.has_timestamp());
1354 EXPECT_EQ(packet17.timestamp(), 70u);
1355 ASSERT_TRUE(packet17.has_frame_timeline_event());
1356
1357 const auto& event17 = packet17.frame_timeline_event();
1358 const auto& actualSkippedDisplayFrameEnd = event17.frame_end();
1359 validateTraceEvent(actualSkippedDisplayFrameEnd, protoSkippedActualDisplayFrameEnd);
1360}
1361
Adithya Srinivasan01189672020-10-20 14:23:05 -07001362TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
1363 auto tracingSession = getTracingSessionForTest();
1364 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001365
1366 tracingSession->StartBlocking();
Ady Abraham57a8ab42023-01-26 15:28:19 -08001367
1368 // Add an empty surface frame so that display frame would get traced.
1369 addEmptySurfaceFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001370 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001371
1372 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001373 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001374 mFrameTimeline->setSfPresent(26, presentFence1);
1375 presentFence1->signalForTest(31);
1376
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001377 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001378 auto protoExpectedDisplayFrameStart =
1379 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1380 kSurfaceFlingerPid);
1381 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1382 auto protoActualDisplayFrameStart =
1383 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
1384 kSurfaceFlingerPid,
1385 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001386 FrameTimelineEvent::JANK_NONE,
Ying Wei96eb5352023-11-21 17:37:21 +00001387 FrameTimelineEvent::SEVERITY_NONE,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001388 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001389 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001390
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001391 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001392 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001393 tracingSession->StopBlocking();
1394
1395 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001396 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001397
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001398 // Packet - 0 : ExpectedDisplayFrameStart
1399 const auto& packet0 = packets[0];
1400 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001401 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001402 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001403
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001404 const auto& event0 = packet0.frame_timeline_event();
1405 ASSERT_TRUE(event0.has_expected_display_frame_start());
1406 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
1407 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
1408
1409 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
1410 const auto& packet1 = packets[1];
1411 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001412 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001413 ASSERT_TRUE(packet1.has_frame_timeline_event());
1414
1415 const auto& event1 = packet1.frame_timeline_event();
1416 ASSERT_TRUE(event1.has_frame_end());
1417 const auto& expectedDisplayFrameEnd = event1.frame_end();
1418 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
1419
1420 // Packet - 2 : ActualDisplayFrameStart
1421 const auto& packet2 = packets[2];
1422 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001423 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001424 ASSERT_TRUE(packet2.has_frame_timeline_event());
1425
1426 const auto& event2 = packet2.frame_timeline_event();
1427 ASSERT_TRUE(event2.has_actual_display_frame_start());
1428 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1429 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1430
1431 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1432 const auto& packet3 = packets[3];
1433 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001434 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001435 ASSERT_TRUE(packet3.has_frame_timeline_event());
1436
1437 const auto& event3 = packet3.frame_timeline_event();
1438 ASSERT_TRUE(event3.has_frame_end());
1439 const auto& actualDisplayFrameEnd = event3.frame_end();
1440 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001441}
1442
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001443TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1444 auto tracingSession = getTracingSessionForTest();
1445 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1446
1447 tracingSession->StartBlocking();
1448 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1449 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001450 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001451
Ady Abraham57a8ab42023-01-26 15:28:19 -08001452 // Add an empty surface frame so that display frame would get traced.
1453 addEmptySurfaceFrame();
1454
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001455 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001456 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001457 mFrameTimeline->setSfPresent(26, presentFence1);
1458 presentFence1->signalForTest(31);
1459
1460 int64_t traceCookie = snoopCurrentTraceCookie();
1461
1462 auto protoActualDisplayFrameStart =
1463 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1464 kSurfaceFlingerPid,
1465 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001466 false, FrameTimelineEvent::JANK_UNKNOWN,
Ying Wei96eb5352023-11-21 17:37:21 +00001467 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001468 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001469 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1470
1471 addEmptyDisplayFrame();
1472 flushTrace();
1473 tracingSession->StopBlocking();
1474
1475 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1476 // Only actual timeline packets should be in the trace
1477 EXPECT_EQ(packets.size(), 2u);
1478
1479 // Packet - 0 : ActualDisplayFrameStart
1480 const auto& packet0 = packets[0];
1481 ASSERT_TRUE(packet0.has_timestamp());
1482 EXPECT_EQ(packet0.timestamp(), 20u);
1483 ASSERT_TRUE(packet0.has_frame_timeline_event());
1484
1485 const auto& event0 = packet0.frame_timeline_event();
1486 ASSERT_TRUE(event0.has_actual_display_frame_start());
1487 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1488 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1489
1490 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1491 const auto& packet1 = packets[1];
1492 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001493 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001494 ASSERT_TRUE(packet1.has_frame_timeline_event());
1495
1496 const auto& event1 = packet1.frame_timeline_event();
1497 ASSERT_TRUE(event1.has_frame_end());
1498 const auto& actualDisplayFrameEnd = event1.frame_end();
1499 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1500}
1501
Adithya Srinivasan01189672020-10-20 14:23:05 -07001502TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1503 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001504 // Layer specific increment
Edgar Arriaga631e4252023-03-02 02:11:24 +00001505 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001506 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1507 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1508
1509 tracingSession->StartBlocking();
1510 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1511 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001512
Huihong Luo3bdef862022-03-03 11:57:19 -08001513 FrameTimelineInfo ftInfo;
1514 ftInfo.vsyncId = surfaceFrameToken;
1515 ftInfo.inputEventId = sInputEventId;
1516
Adithya Srinivasan01189672020-10-20 14:23:05 -07001517 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001518 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1519 sLayerNameOne, sLayerNameOne,
1520 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001521 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001522 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1523 sLayerNameOne, sLayerNameOne,
1524 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001525 surfaceFrame1->setActualQueueTime(10);
1526 surfaceFrame1->setDropTime(15);
1527
1528 surfaceFrame2->setActualQueueTime(15);
1529 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001530
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001531 // First 2 cookies will be used by the DisplayFrame
1532 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1533
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001534 auto protoDroppedSurfaceFrameExpectedStart =
1535 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1536 displayFrameToken1, sPidOne, sLayerNameOne);
1537 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1538 auto protoDroppedSurfaceFrameActualStart =
1539 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1540 displayFrameToken1, sPidOne, sLayerNameOne,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001541 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1542 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001543 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001544 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001545 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001546
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001547 auto protoPresentedSurfaceFrameExpectedStart =
1548 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1549 displayFrameToken1, sPidOne, sLayerNameOne);
1550 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1551 auto protoPresentedSurfaceFrameActualStart =
1552 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1553 displayFrameToken1, sPidOne, sLayerNameOne,
1554 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001555 FrameTimelineEvent::JANK_NONE,
Ying Wei96eb5352023-11-21 17:37:21 +00001556 FrameTimelineEvent::SEVERITY_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001557 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001558 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001559
1560 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001561 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001562 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1563 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001564 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001565 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001566 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001567 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001568
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001569 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001570 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001571 tracingSession->StopBlocking();
1572
1573 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001574 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1575 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001576
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001577 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001578 const auto& packet4 = packets[4];
1579 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001580 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001581 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001582
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001583 const auto& event4 = packet4.frame_timeline_event();
1584 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001585 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1586 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001587
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001588 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001589 const auto& packet5 = packets[5];
1590 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001591 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001592 ASSERT_TRUE(packet5.has_frame_timeline_event());
1593
1594 const auto& event5 = packet5.frame_timeline_event();
1595 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001596 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1597 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001598
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001599 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001600 const auto& packet6 = packets[6];
1601 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001602 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001603 ASSERT_TRUE(packet6.has_frame_timeline_event());
1604
1605 const auto& event6 = packet6.frame_timeline_event();
1606 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001607 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1608 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001609
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001610 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001611 const auto& packet7 = packets[7];
1612 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001613 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001614 ASSERT_TRUE(packet7.has_frame_timeline_event());
1615
1616 const auto& event7 = packet7.frame_timeline_event();
1617 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001618 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1619 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1620
1621 // Packet - 8 : ExpectedSurfaceFrameStart2
1622 const auto& packet8 = packets[8];
1623 ASSERT_TRUE(packet8.has_timestamp());
1624 EXPECT_EQ(packet8.timestamp(), 10u);
1625 ASSERT_TRUE(packet8.has_frame_timeline_event());
1626
1627 const auto& event8 = packet8.frame_timeline_event();
1628 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1629 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1630 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1631
1632 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1633 const auto& packet9 = packets[9];
1634 ASSERT_TRUE(packet9.has_timestamp());
1635 EXPECT_EQ(packet9.timestamp(), 25u);
1636 ASSERT_TRUE(packet9.has_frame_timeline_event());
1637
1638 const auto& event9 = packet9.frame_timeline_event();
1639 ASSERT_TRUE(event9.has_frame_end());
1640 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1641 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1642
1643 // Packet - 10 : ActualSurfaceFrameStart2
1644 const auto& packet10 = packets[10];
1645 ASSERT_TRUE(packet10.has_timestamp());
1646 EXPECT_EQ(packet10.timestamp(), 10u);
1647 ASSERT_TRUE(packet10.has_frame_timeline_event());
1648
1649 const auto& event10 = packet10.frame_timeline_event();
1650 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1651 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1652 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1653
1654 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1655 const auto& packet11 = packets[11];
1656 ASSERT_TRUE(packet11.has_timestamp());
1657 EXPECT_EQ(packet11.timestamp(), 20u);
1658 ASSERT_TRUE(packet11.has_frame_timeline_event());
1659
1660 const auto& event11 = packet11.frame_timeline_event();
1661 ASSERT_TRUE(event11.has_frame_end());
1662 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1663 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1664}
1665
Ady Abrahame43ff722022-02-15 14:44:25 -08001666TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredIsAppMissedDeadline) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001667 auto tracingSession = getTracingSessionForTest();
1668 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1669
1670 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001671 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1672 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1673 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001674 int64_t surfaceFrameToken =
1675 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1676
1677 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001678 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001679 FrameTimelineInfo ftInfo;
1680 ftInfo.vsyncId = surfaceFrameToken;
1681 ftInfo.inputEventId = 0;
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001682 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001683 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1684 sLayerNameOne, sLayerNameOne,
1685 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001686 surfaceFrame1->setActualQueueTime(appEndTime);
1687 surfaceFrame1->setAcquireFenceTime(appEndTime);
1688
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001689 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1690 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1691 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001692 int64_t displayFrameToken =
1693 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1694
1695 // First 2 cookies will be used by the DisplayFrame
1696 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1697
1698 auto protoActualSurfaceFrameStart =
1699 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1700 displayFrameToken, sPidOne, sLayerNameOne,
1701 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Ady Abrahame43ff722022-02-15 14:44:25 -08001702 false, FrameTimelineEvent::JANK_APP_DEADLINE_MISSED,
Ying Wei96eb5352023-11-21 17:37:21 +00001703 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001704 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001705 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1706
1707 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001708 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001709 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1710 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1711 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1712 presentFence1->signalForTest(sfPresentTime);
1713
1714 addEmptyDisplayFrame();
1715 flushTrace();
1716 tracingSession->StopBlocking();
1717
1718 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1719 // Display Frame 4 packets + SurfaceFrame 2 packets
1720 ASSERT_EQ(packets.size(), 6u);
1721
1722 // Packet - 4 : ActualSurfaceFrameStart
1723 const auto& packet4 = packets[4];
1724 ASSERT_TRUE(packet4.has_timestamp());
1725 EXPECT_EQ(packet4.timestamp(),
1726 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1727 ASSERT_TRUE(packet4.has_frame_timeline_event());
1728
1729 const auto& event4 = packet4.frame_timeline_event();
1730 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1731 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1732 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1733
1734 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1735 const auto& packet5 = packets[5];
1736 ASSERT_TRUE(packet5.has_timestamp());
1737 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1738 ASSERT_TRUE(packet5.has_frame_timeline_event());
1739
1740 const auto& event5 = packet5.frame_timeline_event();
1741 ASSERT_TRUE(event5.has_frame_end());
1742 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001743 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001744}
1745
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001746TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDroppedFramesTracedProperly) {
1747 auto tracingSession = getTracingSessionForTest();
1748 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1749
1750 tracingSession->StartBlocking();
1751 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1752 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1753 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
1754 int64_t surfaceFrameToken =
1755 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1756
1757 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001758 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001759 FrameTimelineInfo ftInfo;
1760 ftInfo.vsyncId = surfaceFrameToken;
1761 ftInfo.inputEventId = 0;
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001762 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001763 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1764 sLayerNameOne, sLayerNameOne,
1765 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001766
1767 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(22ms).count();
1768 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1769 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
1770 int64_t displayFrameToken =
1771 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1772
1773 // First 2 cookies will be used by the DisplayFrame
1774 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1775
1776 auto protoActualSurfaceFrameStart =
1777 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1778 displayFrameToken, sPidOne, sLayerNameOne,
1779 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001780 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001781 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001782 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001783 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1784
1785 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001786 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001787 surfaceFrame1->setDropTime(sfStartTime);
1788 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1789 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1790 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1791 presentFence1->signalForTest(sfPresentTime);
1792
1793 addEmptyDisplayFrame();
1794 flushTrace();
1795 tracingSession->StopBlocking();
1796
1797 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1798 // Display Frame 4 packets + SurfaceFrame 2 packets
1799 ASSERT_EQ(packets.size(), 6u);
1800
1801 // Packet - 4 : ActualSurfaceFrameStart
1802 const auto& packet4 = packets[4];
1803 ASSERT_TRUE(packet4.has_timestamp());
1804 EXPECT_EQ(packet4.timestamp(),
1805 static_cast<uint64_t>(sfStartTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1806 ASSERT_TRUE(packet4.has_frame_timeline_event());
1807
1808 const auto& event4 = packet4.frame_timeline_event();
1809 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1810 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1811 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1812
1813 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1814 const auto& packet5 = packets[5];
1815 ASSERT_TRUE(packet5.has_timestamp());
1816 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(sfStartTime));
1817 ASSERT_TRUE(packet5.has_frame_timeline_event());
1818
1819 const auto& event5 = packet5.frame_timeline_event();
1820 ASSERT_TRUE(event5.has_frame_end());
1821 const auto& actualSurfaceFrameEnd = event5.frame_end();
1822 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
1823}
1824
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001825// Tests for Jank classification
1826TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001827 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001828 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001829 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1830 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001831 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -08001832 FrameTimelineInfo ftInfo;
1833 ftInfo.vsyncId = surfaceFrameToken;
1834 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001835 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -08001836 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1837 sLayerNameOne, sLayerNameOne,
1838 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001839 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001840 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1841 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1842 mFrameTimeline->setSfPresent(26, presentFence1);
1843 auto displayFrame = getDisplayFrame(0);
1844 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1845 presentFence1->signalForTest(29);
1846
1847 // Fences haven't been flushed yet, so it should be 0
1848 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1849 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1850
1851 addEmptyDisplayFrame();
1852 displayFrame = getDisplayFrame(0);
1853
1854 // Fences have flushed, so the present timestamps should be updated
1855 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1856 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1857 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1858 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1859 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00001860 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::None);
Pascal Mütschardd56514e2024-05-24 17:37:13 +02001861
1862 auto jankData = getLayerOneJankData();
1863 EXPECT_EQ(jankData.size(), 1u);
1864 EXPECT_EQ(jankData[0].jankType, JankType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001865}
1866
1867TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001868 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001869 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001870 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1871 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001872 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001873 mFrameTimeline->setSfPresent(26, presentFence1);
1874 auto displayFrame = getDisplayFrame(0);
1875 presentFence1->signalForTest(30);
1876
1877 // Fences for the first frame haven't been flushed yet, so it should be 0
1878 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1879
1880 // Trigger a flush by finalizing the next DisplayFrame
1881 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001882 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001883 mFrameTimeline->setSfPresent(56, presentFence2);
1884 displayFrame = getDisplayFrame(0);
1885
1886 // Fences for the first frame have flushed, so the present timestamps should be updated
1887 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1888 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1889 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1890 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00001891 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001892
1893 // Fences for the second frame haven't been flushed yet, so it should be 0
1894 auto displayFrame2 = getDisplayFrame(1);
1895 presentFence2->signalForTest(65);
1896 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001897 addEmptyDisplayFrame();
1898 displayFrame2 = getDisplayFrame(1);
1899
1900 // Fences for the second frame have flushed, so the present timestamps should be updated
1901 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1902 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1903 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1904 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00001905 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001906}
1907
1908TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001909 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001910 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001911 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1912 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001913 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001914 mFrameTimeline->setSfPresent(26, presentFence1);
1915 auto displayFrame = getDisplayFrame(0);
1916 presentFence1->signalForTest(50);
1917
1918 // Fences for the first frame haven't been flushed yet, so it should be 0
1919 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1920
1921 // Trigger a flush by finalizing the next DisplayFrame
1922 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001923 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001924 mFrameTimeline->setSfPresent(56, presentFence2);
1925 displayFrame = getDisplayFrame(0);
1926
1927 // Fences for the first frame have flushed, so the present timestamps should be updated
1928 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1929 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1930 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1931 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00001932 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001933
1934 // Fences for the second frame haven't been flushed yet, so it should be 0
1935 auto displayFrame2 = getDisplayFrame(1);
1936 presentFence2->signalForTest(75);
1937 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1938
1939 addEmptyDisplayFrame();
1940 displayFrame2 = getDisplayFrame(1);
1941
1942 // Fences for the second frame have flushed, so the present timestamps should be updated
1943 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1944 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1945 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1946 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00001947 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001948}
1949
1950TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001951 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1952 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001953 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001954
1955 mFrameTimeline->setSfPresent(22, presentFence1);
1956 auto displayFrame = getDisplayFrame(0);
1957 presentFence1->signalForTest(28);
1958
1959 // Fences haven't been flushed yet, so it should be 0
1960 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1961
1962 addEmptyDisplayFrame();
1963 displayFrame = getDisplayFrame(0);
1964
1965 // Fences have flushed, so the present timestamps should be updated
1966 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1967 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1968 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1969 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00001970 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001971}
1972
1973TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001974 /*
1975 * Case 1 - cpu time > vsync period but combined time > deadline > deadline -> cpudeadlinemissed
1976 * Case 2 - cpu time < vsync period but combined time > deadline -> gpudeadlinemissed
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001977 * Case 3 - previous frame ran longer -> sf_stuffing
1978 * Case 4 - Long cpu under SF stuffing -> cpudeadlinemissed
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001979 */
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001980 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001981 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001982 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1983 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001984 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1985 auto gpuFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001986 auto gpuFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1987 auto gpuFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001988 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001989 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001990 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1991 int64_t sfToken4 = mTokenManager->generateTokenForPredictions({112, 120, 120});
1992
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001993 // case 1 - cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001994 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001995 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
1996 auto displayFrame0 = getDisplayFrame(0);
1997 gpuFence1->signalForTest(36);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001998 presentFence1->signalForTest(52);
1999
2000 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00002001 EXPECT_EQ(displayFrame0->getActuals().presentTime, 0);
2002
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002003 // case 2 - cpu time = 56 - 52 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002004 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00002005 mFrameTimeline->setSfPresent(56, presentFence2, gpuFence2);
2006 auto displayFrame1 = getDisplayFrame(1);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002007 gpuFence2->signalForTest(76);
2008 presentFence2->signalForTest(90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00002009
2010 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2011 // Fences have flushed for first displayFrame, so the present timestamps should be updated
2012 EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
2013 EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2014 EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Rachel Lee94917b32022-03-18 17:52:09 -07002015 EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002016 EXPECT_EQ(displayFrame0->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002017
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002018 // case 3 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002019 mFrameTimeline->setSfWakeUp(sfToken3, 106, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002020 mFrameTimeline->setSfPresent(112, presentFence3, gpuFence3);
2021 auto displayFrame2 = getDisplayFrame(2);
2022 gpuFence3->signalForTest(116);
2023 presentFence3->signalForTest(120);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002024
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002025 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00002026 // Fences have flushed for second displayFrame, so the present timestamps should be updated
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002027 EXPECT_EQ(displayFrame1->getActuals().presentTime, 90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00002028 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2029 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2030 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002031 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002032
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002033 // case 4 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002034 mFrameTimeline->setSfWakeUp(sfToken4, 120, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002035 mFrameTimeline->setSfPresent(140, presentFence4, gpuFence4);
2036 auto displayFrame3 = getDisplayFrame(3);
2037 gpuFence4->signalForTest(156);
2038 presentFence4->signalForTest(180);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002039
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002040 EXPECT_EQ(displayFrame3->getActuals().presentTime, 0);
2041 // Fences have flushed for third displayFrame, so the present timestamps should be updated
2042 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
2043 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2044 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2045 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00002046 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002047
2048 addEmptyDisplayFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002049
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002050 // Fences have flushed for third displayFrame, so the present timestamps should be updated
2051 EXPECT_EQ(displayFrame3->getActuals().presentTime, 180);
2052 EXPECT_EQ(displayFrame3->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2053 EXPECT_EQ(displayFrame3->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2054 EXPECT_EQ(displayFrame3->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002055 EXPECT_EQ(displayFrame3->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002056}
2057
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002058TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08002059 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002060 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002061 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
2062 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002063 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
2064 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08002065 FrameTimelineInfo ftInfo;
2066 ftInfo.vsyncId = surfaceFrameToken1;
2067 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002068 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002069 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2070 sLayerNameOne, sLayerNameOne,
2071 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002072 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002073 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002074 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2075 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002076 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002077 auto displayFrame1 = getDisplayFrame(0);
2078 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2079 presentFence1->signalForTest(30);
2080
2081 // Fences for the first frame haven't been flushed yet, so it should be 0
2082 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2083 auto actuals1 = presentedSurfaceFrame1.getActuals();
2084 EXPECT_EQ(actuals1.presentTime, 0);
2085
2086 // Trigger a flush by finalizing the next DisplayFrame
2087 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002088 FrameTimelineInfo ftInfo2;
2089 ftInfo2.vsyncId = surfaceFrameToken2;
2090 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002091 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002092 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2093 sLayerNameOne, sLayerNameOne,
2094 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002095 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002096 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002097 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2098 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002099 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002100 auto displayFrame2 = getDisplayFrame(1);
2101 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2102
2103 // Fences for the first frame have flushed, so the present timestamps should be updated
2104 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
2105 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2106 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2107 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00002108 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002109
2110 actuals1 = presentedSurfaceFrame1.getActuals();
2111 EXPECT_EQ(actuals1.presentTime, 30);
2112 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2113 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2114 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00002115 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002116
2117 // Fences for the second frame haven't been flushed yet, so it should be 0
2118 presentFence2->signalForTest(65);
2119 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2120 auto actuals2 = presentedSurfaceFrame2.getActuals();
2121 EXPECT_EQ(actuals2.presentTime, 0);
2122
Alec Mouri363faf02021-01-29 16:34:55 -08002123 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
2124
2125 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002126 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
2127 sLayerNameOne, sGameMode,
2128 JankType::PredictionError, -3, 5,
2129 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08002130
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002131 addEmptyDisplayFrame();
2132
2133 // Fences for the second frame have flushed, so the present timestamps should be updated
2134 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
2135 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2136 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2137 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002138 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002139
2140 actuals2 = presentedSurfaceFrame2.getActuals();
2141 EXPECT_EQ(actuals2.presentTime, 65);
2142 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2143 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2144 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002145 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002146}
2147
2148TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08002149 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002150 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002151 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
2152 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002153 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
2154 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08002155 FrameTimelineInfo ftInfo;
2156 ftInfo.vsyncId = surfaceFrameToken1;
2157 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002158 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002159 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2160 sLayerNameOne, sLayerNameOne,
2161 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002162 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002163 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002164 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2165 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2166 mFrameTimeline->setSfPresent(26, presentFence1);
2167 auto displayFrame1 = getDisplayFrame(0);
2168 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2169 presentFence1->signalForTest(50);
2170
2171 // Fences for the first frame haven't been flushed yet, so it should be 0
2172 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2173 auto actuals1 = presentedSurfaceFrame1.getActuals();
2174 EXPECT_EQ(actuals1.presentTime, 0);
2175
2176 // Trigger a flush by finalizing the next DisplayFrame
2177 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002178 FrameTimelineInfo ftInfo2;
2179 ftInfo2.vsyncId = surfaceFrameToken2;
2180 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002181 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002182 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2183 sLayerNameOne, sLayerNameOne,
2184 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002185 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002186 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002187 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2188 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002189 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002190 auto displayFrame2 = getDisplayFrame(1);
2191 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2192
2193 // Fences for the first frame have flushed, so the present timestamps should be updated
2194 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
2195 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2196 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2197 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002198 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002199
2200 actuals1 = presentedSurfaceFrame1.getActuals();
2201 EXPECT_EQ(actuals1.presentTime, 50);
2202 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2203 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2204 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002205 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002206
2207 // Fences for the second frame haven't been flushed yet, so it should be 0
2208 presentFence2->signalForTest(86);
2209 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2210 auto actuals2 = presentedSurfaceFrame2.getActuals();
2211 EXPECT_EQ(actuals2.presentTime, 0);
2212
Alec Mouri363faf02021-01-29 16:34:55 -08002213 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
2214
2215 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002216 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
2217 sLayerNameOne, sGameMode,
2218 JankType::PredictionError, -3, 5,
2219 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08002220
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002221 addEmptyDisplayFrame();
2222
2223 // Fences for the second frame have flushed, so the present timestamps should be updated
2224 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
2225 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2226 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2227 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002228 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002229
2230 actuals2 = presentedSurfaceFrame2.getActuals();
2231 EXPECT_EQ(actuals2.presentTime, 86);
2232 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2233 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2234 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002235 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002236}
2237
2238TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08002239 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08002240
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002241 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002242 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002243 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -08002244 FrameTimelineInfo ftInfo;
2245 ftInfo.vsyncId = surfaceFrameToken1;
2246 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002247 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002248 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2249 sLayerNameOne, sLayerNameOne,
2250 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002251 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002252 mFrameTimeline->setSfWakeUp(sfToken1, 42, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002253 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2254 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2255 mFrameTimeline->setSfPresent(46, presentFence1);
2256 auto displayFrame1 = getDisplayFrame(0);
2257 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2258 presentFence1->signalForTest(50);
2259
2260 // Fences for the first frame haven't been flushed yet, so it should be 0
2261 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2262 auto actuals1 = presentedSurfaceFrame1.getActuals();
2263 EXPECT_EQ(actuals1.presentTime, 0);
2264
2265 addEmptyDisplayFrame();
2266
2267 // Fences for the first frame have flushed, so the present timestamps should be updated
2268 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
2269 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2270 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2271 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002272 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002273
2274 actuals1 = presentedSurfaceFrame1.getActuals();
2275 EXPECT_EQ(actuals1.presentTime, 50);
2276 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2277 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2278 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +00002279 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002280}
2281
2282TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002283 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as only
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002284 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002285 // jank to the SurfaceFrame along with AppDeadlineMissed.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002286
Alec Mouri363faf02021-01-29 16:34:55 -08002287 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002288 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002289 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
2290 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002291 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
2292 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
Huihong Luo3bdef862022-03-03 11:57:19 -08002293 FrameTimelineInfo ftInfo;
2294 ftInfo.vsyncId = surfaceFrameToken1;
2295 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002296 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002297 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2298 sLayerNameOne, sLayerNameOne,
2299 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002300 surfaceFrame1->setAcquireFenceTime(26);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002301 mFrameTimeline->setSfWakeUp(sfToken1, 32, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002302 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2303 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2304 mFrameTimeline->setSfPresent(36, presentFence1);
2305 auto displayFrame1 = getDisplayFrame(0);
2306 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2307 presentFence1->signalForTest(40);
2308
2309 // Fences for the first frame haven't been flushed yet, so it should be 0
2310 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2311 auto actuals1 = presentedSurfaceFrame1.getActuals();
2312 EXPECT_EQ(actuals1.presentTime, 0);
2313
2314 // Trigger a flush by finalizing the next DisplayFrame
2315 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002316 FrameTimelineInfo ftInfo2;
2317 ftInfo2.vsyncId = surfaceFrameToken2;
2318 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002319 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002320 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2321 sLayerNameOne, sLayerNameOne,
2322 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002323 surfaceFrame2->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002324 mFrameTimeline->setSfWakeUp(sfToken2, 43, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002325 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2326 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2327 mFrameTimeline->setSfPresent(56, presentFence2);
2328 auto displayFrame2 = getDisplayFrame(1);
2329 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2330
2331 // Fences for the first frame have flushed, so the present timestamps should be updated
2332 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
2333 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2334 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2335 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002336 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002337
2338 actuals1 = presentedSurfaceFrame1.getActuals();
2339 EXPECT_EQ(actuals1.presentTime, 40);
2340 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2341 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2342 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002343 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002344
2345 // Fences for the second frame haven't been flushed yet, so it should be 0
2346 presentFence2->signalForTest(60);
2347 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2348 auto actuals2 = presentedSurfaceFrame2.getActuals();
2349 EXPECT_EQ(actuals2.presentTime, 0);
2350
2351 addEmptyDisplayFrame();
2352
2353 // Fences for the second frame have flushed, so the present timestamps should be updated
2354 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
2355 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2356 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2357 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002358 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002359
2360 actuals2 = presentedSurfaceFrame2.getActuals();
2361 EXPECT_EQ(actuals2.presentTime, 60);
2362 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2363 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002364 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2365 JankType::SurfaceFlingerCpuDeadlineMissed | JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002366 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002367}
2368
2369TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002370 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08002371 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002372 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2373 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2374 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2375
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002376 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2377 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Huihong Luo3bdef862022-03-03 11:57:19 -08002378 FrameTimelineInfo ftInfo;
2379 ftInfo.vsyncId = surfaceFrameToken1;
2380 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002381 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002382 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2383 sLayerNameOne, sLayerNameOne,
2384 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002385 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002386 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002387 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2388 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2389 mFrameTimeline->setSfPresent(56, presentFence1);
2390 auto displayFrame1 = getDisplayFrame(0);
2391 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2392 presentFence1->signalForTest(60);
2393
2394 // Fences for the first frame haven't been flushed yet, so it should be 0
2395 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2396 auto actuals1 = presentedSurfaceFrame1.getActuals();
2397 EXPECT_EQ(actuals1.presentTime, 0);
2398
2399 // Trigger a flush by finalizing the next DisplayFrame
2400 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002401 FrameTimelineInfo ftInfo2;
2402 ftInfo2.vsyncId = surfaceFrameToken2;
2403 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002404 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002405 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2406 sLayerNameOne, sLayerNameOne,
2407 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002408 surfaceFrame2->setAcquireFenceTime(84);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002409 mFrameTimeline->setSfWakeUp(sfToken2, 112, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002410 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2411 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2412 mFrameTimeline->setSfPresent(116, presentFence2);
2413 auto displayFrame2 = getDisplayFrame(1);
2414 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2415 presentFence2->signalForTest(120);
2416
2417 // Fences for the first frame have flushed, so the present timestamps should be updated
2418 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2419 actuals1 = presentedSurfaceFrame1.getActuals();
2420 EXPECT_EQ(actuals1.endTime, 50);
2421 EXPECT_EQ(actuals1.presentTime, 60);
2422
2423 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2424 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2425 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002426 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002427
2428 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2429 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2430 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002431 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002432
2433 // Fences for the second frame haven't been flushed yet, so it should be 0
2434 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2435 auto actuals2 = presentedSurfaceFrame2.getActuals();
2436 EXPECT_EQ(actuals2.presentTime, 0);
2437
2438 addEmptyDisplayFrame();
2439
2440 // Fences for the second frame have flushed, so the present timestamps should be updated
2441 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
2442 actuals2 = presentedSurfaceFrame2.getActuals();
2443 EXPECT_EQ(actuals2.presentTime, 120);
2444
2445 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2446 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2447 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002448 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002449
2450 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2451 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2452 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2453 JankType::AppDeadlineMissed | JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00002454 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002455}
Alec Mouriadebf5c2021-01-05 12:57:36 -08002456
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002457TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
2458 // Layer specific increment
2459 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
2460 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2461 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2462 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2463
2464 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2465 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -08002466 FrameTimelineInfo ftInfo;
2467 ftInfo.vsyncId = surfaceFrameToken1;
2468 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002469 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002470 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2471 sLayerNameOne, sLayerNameOne,
2472 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002473 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002474 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002475 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2476 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2477 mFrameTimeline->setSfPresent(56, presentFence1);
2478 auto displayFrame1 = getDisplayFrame(0);
2479 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2480 presentFence1->signalForTest(60);
2481
2482 // Fences for the first frame haven't been flushed yet, so it should be 0
2483 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2484 auto actuals1 = presentedSurfaceFrame1.getActuals();
2485 EXPECT_EQ(actuals1.presentTime, 0);
2486
2487 // Trigger a flush by finalizing the next DisplayFrame
2488 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002489 FrameTimelineInfo ftInfo2;
2490 ftInfo2.vsyncId = surfaceFrameToken2;
2491 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002492 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002493 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2494 sLayerNameOne, sLayerNameOne,
2495 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002496 surfaceFrame2->setAcquireFenceTime(80);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002497 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002498 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
2499 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2500 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2501 mFrameTimeline->setSfPresent(86, presentFence2);
2502 auto displayFrame2 = getDisplayFrame(1);
2503 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2504 presentFence2->signalForTest(90);
2505
2506 // Fences for the first frame have flushed, so the present timestamps should be updated
2507 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2508 actuals1 = presentedSurfaceFrame1.getActuals();
2509 EXPECT_EQ(actuals1.endTime, 50);
2510 EXPECT_EQ(actuals1.presentTime, 60);
2511
2512 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2513 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2514 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002515 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002516
2517 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2518 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2519 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002520 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002521
2522 // Fences for the second frame haven't been flushed yet, so it should be 0
2523 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2524 auto actuals2 = presentedSurfaceFrame2.getActuals();
2525 EXPECT_EQ(actuals2.presentTime, 0);
2526
2527 addEmptyDisplayFrame();
2528
2529 // Fences for the second frame have flushed, so the present timestamps should be updated
2530 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2531 actuals2 = presentedSurfaceFrame2.getActuals();
2532 EXPECT_EQ(actuals2.presentTime, 90);
2533
2534 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2535 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2536 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002537 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002538
2539 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2540 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2541 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00002542 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002543}
2544
Rachel Lee94917b32022-03-18 17:52:09 -07002545TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent_GpuAndCpuMiss) {
2546 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2547 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2548 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2549 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2550 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2551
2552 // Case 1: cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002553 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Rachel Lee94917b32022-03-18 17:52:09 -07002554 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
2555 auto displayFrame = getDisplayFrame(0);
2556 gpuFence1->signalForTest(36);
2557 presentFence1->signalForTest(52);
2558
2559 // Fences haven't been flushed yet, so it should be 0
2560 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
2561
2562 addEmptyDisplayFrame();
2563 displayFrame = getDisplayFrame(0);
2564
2565 // Fences have flushed, so the present timestamps should be updated
2566 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
2567 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2568 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2569 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002570 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Full);
Rachel Lee94917b32022-03-18 17:52:09 -07002571
2572 // Case 2: No GPU fence so it will not use GPU composition.
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002573 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Rachel Lee94917b32022-03-18 17:52:09 -07002574 mFrameTimeline->setSfPresent(66, presentFence2);
2575 auto displayFrame2 = getDisplayFrame(2); // 2 because of previous empty frame
2576 presentFence2->signalForTest(90);
2577
2578 // Fences for the frame haven't been flushed yet, so it should be 0
2579 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2580
2581 addEmptyDisplayFrame();
2582
2583 // Fences have flushed, so the present timestamps should be updated
2584 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2585 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2586 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2587 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002588 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Rachel Lee94917b32022-03-18 17:52:09 -07002589}
2590
Ady Abrahamfcb16862022-10-10 14:35:21 -07002591TEST_F(FrameTimelineTest, jankClassification_presentFenceError) {
2592 auto erroneousPresentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2593 auto erroneousPresentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2594 auto validPresentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2595 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2596 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2597 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({72, 80, 80});
2598
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002599 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002600 mFrameTimeline->setSfPresent(26, erroneousPresentFence1);
2601
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002602 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002603 mFrameTimeline->setSfPresent(60, erroneousPresentFence2);
2604
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002605 mFrameTimeline->setSfWakeUp(sfToken3, 72, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002606 mFrameTimeline->setSfPresent(80, validPresentFence);
2607
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002608 erroneousPresentFence2->signalForTest(2);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002609 validPresentFence->signalForTest(80);
2610
2611 addEmptyDisplayFrame();
2612
2613 {
2614 auto displayFrame = getDisplayFrame(0);
2615 EXPECT_EQ(displayFrame->getActuals().presentTime, 26);
2616 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2617 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002618 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002619 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002620 }
2621 {
2622 auto displayFrame = getDisplayFrame(1);
2623 EXPECT_EQ(displayFrame->getActuals().presentTime, 60);
2624 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2625 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002626 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002627 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002628 }
2629 {
2630 auto displayFrame = getDisplayFrame(2);
2631 EXPECT_EQ(displayFrame->getActuals().presentTime, 80);
2632 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2633 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2634 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002635 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::None);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002636 }
2637}
2638
Alec Mouriadebf5c2021-01-05 12:57:36 -08002639TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
2640 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
2641}
2642
2643TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002644 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002645
2646 auto surfaceFrame1 =
2647 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002648 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002649 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002650 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2651 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2652 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2653 presentFence1->signalForTest(oneHundredMs);
2654 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2655
2656 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2657}
2658
2659TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002660 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2661 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002662 auto surfaceFrame1 =
2663 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002664 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002665 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002666 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2667 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2668 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2669 presentFence1->signalForTest(oneHundredMs);
2670 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2671
2672 auto surfaceFrame2 =
2673 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002674 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002675 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002676 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2677 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2678 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2679 presentFence2->signalForTest(twoHundredMs);
2680 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2681
2682 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
2683}
2684
2685TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002686 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2687 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002688 auto surfaceFrame1 =
2689 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002690 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002691 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002692 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2693 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2694 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2695 presentFence1->signalForTest(oneHundredMs);
2696 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2697
2698 auto surfaceFrame2 =
2699 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002700 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002701 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002702 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2703 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2704 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2705 presentFence2->signalForTest(twoHundredMs);
2706 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2707
2708 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
2709}
2710
2711TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002712 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2713 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002714 auto surfaceFrame1 =
2715 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002716 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002717 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002718 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2719 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2720 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2721 presentFence1->signalForTest(oneHundredMs);
2722 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2723
2724 auto surfaceFrame2 =
2725 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002726 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002727 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002728 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2729 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2730 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2731 presentFence2->signalForTest(twoHundredMs);
2732 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2733
2734 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2735}
2736
2737TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002738 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2739 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2740 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2741 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2742 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002743 auto surfaceFrame1 =
2744 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002745 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002746 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002747 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2748 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2749 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2750 presentFence1->signalForTest(oneHundredMs);
2751 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2752
2753 auto surfaceFrame2 =
2754 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002755 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002756 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002757 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2758 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2759 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2760 presentFence2->signalForTest(twoHundredMs);
2761 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2762
2763 auto surfaceFrame3 =
2764 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002765 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002766 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002767 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2768 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2769 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2770 presentFence3->signalForTest(threeHundredMs);
2771 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2772
2773 auto surfaceFrame4 =
2774 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002775 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002776 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002777 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2778 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2779 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2780 presentFence4->signalForTest(fiveHundredMs);
2781 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2782
2783 auto surfaceFrame5 =
2784 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002785 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002786 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002787 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2788 // Dropped frames will be excluded from fps computation
2789 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2790 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2791 presentFence5->signalForTest(sixHundredMs);
2792 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2793
2794 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2795}
2796
ramindaniea2bb822022-06-27 19:52:10 +00002797TEST_F(FrameTimelineTest, getMinTime) {
2798 // Use SurfaceFrame::getBaseTime to test the getMinTime.
2799 FrameTimelineInfo ftInfo;
2800
2801 // Valid prediction state test.
2802 ftInfo.vsyncId = 0L;
2803 mTokenManager->generateTokenForPredictions({10});
2804 auto surfaceFrame =
2805 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2806 sLayerNameOne, sLayerNameOne,
2807 /*isBuffer*/ true, sGameMode);
2808 ASSERT_EQ(surfaceFrame->getBaseTime(), 10);
2809
2810 // Test prediction state which is not valid.
2811 ftInfo.vsyncId = FrameTimelineInfo::INVALID_VSYNC_ID;
2812 surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2813 sLayerNameOne, sLayerNameOne,
2814 /*isBuffer*/ true, sGameMode);
2815 // Start time test.
2816 surfaceFrame->setActualStartTime(200);
2817 ASSERT_EQ(surfaceFrame->getBaseTime(), 200);
2818
2819 // End time test.
2820 surfaceFrame->setAcquireFenceTime(100);
2821 ASSERT_EQ(surfaceFrame->getBaseTime(), 100);
2822
2823 // Present time test.
2824 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2825 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2826 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2827 presentFence->signalForTest(std::chrono::nanoseconds(50ns).count());
2828 mFrameTimeline->setSfPresent(50, presentFence);
2829 ASSERT_EQ(surfaceFrame->getBaseTime(), 50);
2830}
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002831
2832TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingDisplayRate) {
2833 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2834 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2835 FrameTimelineInfo ftInfo;
2836 ftInfo.vsyncId = token1;
2837 ftInfo.inputEventId = sInputEventId;
2838 auto surfaceFrame =
2839 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2840 sLayerNameOne, sLayerNameOne,
2841 /*isBuffer*/ true, sGameMode);
2842
2843 mFrameTimeline->setSfWakeUp(token1, 20, RR_30, RR_11);
2844 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2845 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2846 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2847 mFrameTimeline->setSfPresent(50, presentFence1);
2848
2849 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 11);
2850}
2851
2852TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingAppFrameRate) {
2853 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2854 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2855 FrameTimelineInfo ftInfo;
2856 ftInfo.vsyncId = token1;
2857 ftInfo.inputEventId = sInputEventId;
2858 auto surfaceFrame =
2859 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2860 sLayerNameOne, sLayerNameOne,
2861 /*isBuffer*/ true, sGameMode);
2862 surfaceFrame->setRenderRate(RR_30);
2863 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
2864 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2865 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2866 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2867 mFrameTimeline->setSfPresent(50, presentFence1);
2868
2869 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 30);
2870}
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002871} // namespace android::frametimeline