blob: 25437ca856e1a4a81ccad90672ebf4bbf5c7092f [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
482TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000483 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
484 "acquireFenceAfterQueue",
485 "acquireFenceAfterQueue",
486 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700487 surfaceFrame->setActualQueueTime(456);
488 surfaceFrame->setAcquireFenceTime(123);
489 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
490}
491
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700492TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
493 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
494 presentFence->signalForTest(2);
495
496 // Size shouldn't exceed maxDisplayFrames - 64
497 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700498 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800499 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000500 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000501 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700502 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200503 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800504 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
505 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700506 mFrameTimeline->setSfPresent(27, presentFence);
507 }
508 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
509
510 // Increase the size to 256
511 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000512 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700513
514 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700515 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800516 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000517 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000518 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700519 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200520 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800521 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
522 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700523 mFrameTimeline->setSfPresent(27, presentFence);
524 }
525 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
526
527 // Shrink the size to 128
528 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000529 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700530
531 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700532 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800533 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000534 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000535 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700536 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200537 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800538 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
539 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700540 mFrameTimeline->setSfPresent(27, presentFence);
541 }
542 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
543}
Alec Mouri9a29e672020-09-14 12:39:14 -0700544
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000545TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200546 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000547
548 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
549 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
550 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800551 FrameTimelineInfo ftInfo;
552 ftInfo.vsyncId = surfaceFrameToken1;
553 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000554
555 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800556 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
557 sLayerNameOne, sLayerNameOne,
558 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200559 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000560 surfaceFrame1->setAcquireFenceTime(20);
561 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
562 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
563
564 mFrameTimeline->setSfPresent(59, presentFence1);
565 presentFence1->signalForTest(-1);
566 addEmptyDisplayFrame();
567
568 auto displayFrame0 = getDisplayFrame(0);
Ady Abrahamfcb16862022-10-10 14:35:21 -0700569 EXPECT_EQ(displayFrame0->getActuals().presentTime, 59);
Ady Abrahamb1e10d12023-03-13 15:23:54 -0700570 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +0000571 EXPECT_EQ(displayFrame0->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000572 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
573 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +0000574 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000575}
576
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800577// Tests related to TimeStats
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000578TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200579 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000580 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
581 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
582 int64_t surfaceFrameToken1 = -1;
583 int64_t sfToken1 = -1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800584 FrameTimelineInfo ftInfo;
585 ftInfo.vsyncId = surfaceFrameToken1;
586 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000587
588 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800589 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
590 sLayerNameOne, sLayerNameOne,
591 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200592 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000593 surfaceFrame1->setAcquireFenceTime(20);
594 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
595 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
596 presentFence1->signalForTest(70);
597
598 mFrameTimeline->setSfPresent(59, presentFence1);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200599
600 EXPECT_EQ(getLayerOneJankData().size(), 0u);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000601}
602
Alec Mouri9a29e672020-09-14 12:39:14 -0700603TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200604 Fps refreshRate = RR_11;
Alec Mouri9a29e672020-09-14 12:39:14 -0700605 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800606 incrementJankyFrames(
607 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000608 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000609 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800610 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700611 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000612 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
613 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800614 FrameTimelineInfo ftInfo;
615 ftInfo.vsyncId = surfaceFrameToken1;
616 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000617
Alec Mouri9a29e672020-09-14 12:39:14 -0700618 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800619 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
620 sLayerNameOne, sLayerNameOne,
621 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200622 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000623 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800624 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
625 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000626 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700627
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000628 mFrameTimeline->setSfPresent(62, presentFence1);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200629
630 auto jankData = getLayerOneJankData();
631 EXPECT_EQ(jankData.size(), 1u);
632 EXPECT_EQ(jankData[0].jankType, JankType::SurfaceFlingerCpuDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700633}
634
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000635TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfGpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200636 Fps refreshRate = RR_11;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000637 EXPECT_CALL(*mTimeStats,
638 incrementJankyFrames(
639 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000640 sLayerNameOne, sGameMode,
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000641 JankType::SurfaceFlingerGpuDeadlineMissed, 4, 10,
642 0}));
643 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
644 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
645 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
646 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800647 FrameTimelineInfo ftInfo;
648 ftInfo.vsyncId = surfaceFrameToken1;
649 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000650
651 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800652 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
653 sLayerNameOne, sLayerNameOne,
654 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200655 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000656 surfaceFrame1->setAcquireFenceTime(20);
657 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
658 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
659 gpuFence1->signalForTest(64);
660 presentFence1->signalForTest(70);
661
662 mFrameTimeline->setSfPresent(59, presentFence1, gpuFence1);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200663
664 auto jankData = getLayerOneJankData();
665 EXPECT_EQ(jankData.size(), 1u);
666 EXPECT_EQ(jankData[0].jankType, JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000667}
668
Alec Mouri9a29e672020-09-14 12:39:14 -0700669TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200670 Fps refreshRate = RR_30;
Alec Mouri9a29e672020-09-14 12:39:14 -0700671 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800672 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000673 sLayerNameOne, sGameMode,
674 JankType::DisplayHAL, -4, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800675
Alec Mouri9a29e672020-09-14 12:39:14 -0700676 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000677 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
678 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800679 FrameTimelineInfo ftInfo;
680 ftInfo.vsyncId = surfaceFrameToken1;
681 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000682
Alec Mouri9a29e672020-09-14 12:39:14 -0700683 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800684 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
685 sLayerNameOne, sLayerNameOne,
686 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200687 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800688 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000689 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800690 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000691 presentFence1->signalForTest(90);
692 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800693 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +0000694 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200695
696 auto jankData = getLayerOneJankData();
697 EXPECT_EQ(jankData.size(), 1u);
698 EXPECT_EQ(jankData[0].jankType, JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700699}
700
701TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700702 Fps refreshRate = 11_Hz;
Alec Mouri9a29e672020-09-14 12:39:14 -0700703 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000704 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000705 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000706 JankType::AppDeadlineMissed, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000707 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700708 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000709 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
710 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800711 FrameTimelineInfo ftInfo;
712 ftInfo.vsyncId = surfaceFrameToken1;
713 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000714
Alec Mouri9a29e672020-09-14 12:39:14 -0700715 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800716 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
717 sLayerNameOne, sLayerNameOne,
718 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000719 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200720 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700721
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800722 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
723 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000724 presentFence1->signalForTest(90);
725 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100726
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800727 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000728 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Partial);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200729
730 auto jankData = getLayerOneJankData();
731 EXPECT_EQ(jankData.size(), 1u);
732 EXPECT_EQ(jankData[0].jankType, JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700733}
734
Adithya Srinivasanead17162021-02-18 02:17:37 +0000735TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000736 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000737 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000738 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000739 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000740 JankType::SurfaceFlingerScheduling,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000741 -4, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000742 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000743 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
744 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800745 FrameTimelineInfo ftInfo;
746 ftInfo.vsyncId = surfaceFrameToken1;
747 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000748
Adithya Srinivasanead17162021-02-18 02:17:37 +0000749 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800750 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
751 sLayerNameOne, sLayerNameOne,
752 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000753 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200754 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000755
756 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
757 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000758 presentFence1->signalForTest(60);
759 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000760
761 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +0000762 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200763
764 auto jankData = getLayerOneJankData();
765 EXPECT_EQ(jankData.size(), 1u);
766 EXPECT_EQ(jankData[0].jankType, JankType::SurfaceFlingerScheduling);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000767}
768
769TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000770 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000771 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000772 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000773 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000774 JankType::PredictionError, -4, 5,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000775 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000776 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000777 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
778 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800779 FrameTimelineInfo ftInfo;
780 ftInfo.vsyncId = surfaceFrameToken1;
781 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000782
Adithya Srinivasanead17162021-02-18 02:17:37 +0000783 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800784 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
785 sLayerNameOne, sLayerNameOne,
786 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000787 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200788 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000789
790 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
791 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000792 presentFence1->signalForTest(65);
793 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000794
795 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +0000796 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Partial);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200797
798 auto jankData = getLayerOneJankData();
799 EXPECT_EQ(jankData.size(), 1u);
800 EXPECT_EQ(jankData[0].jankType, JankType::PredictionError);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000801}
802
803TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000804 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000805 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000806 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000807 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000808 JankType::BufferStuffing, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000809 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000810 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000811 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
812 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800813 FrameTimelineInfo ftInfo;
814 ftInfo.vsyncId = surfaceFrameToken1;
815 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000816
Adithya Srinivasanead17162021-02-18 02:17:37 +0000817 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800818 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
819 sLayerNameOne, sLayerNameOne,
820 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000821 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200822 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000823
824 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000825 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000826 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000827 presentFence1->signalForTest(90);
828 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000829
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000830 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +0000831 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200832
833 auto jankData = getLayerOneJankData();
834 EXPECT_EQ(jankData.size(), 1u);
835 EXPECT_EQ(jankData[0].jankType, JankType::BufferStuffing);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000836}
837
Alec Mouri363faf02021-01-29 16:34:55 -0800838TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200839 Fps refreshRate = RR_11;
840 Fps renderRate = RR_30;
Alec Mouri363faf02021-01-29 16:34:55 -0800841 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000842 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne,
843 sLayerNameOne, sGameMode,
844 JankType::AppDeadlineMissed, -4, 0,
845 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800846 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000847 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
848 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800849 FrameTimelineInfo ftInfo;
850 ftInfo.vsyncId = surfaceFrameToken1;
851 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000852
Alec Mouri363faf02021-01-29 16:34:55 -0800853 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800854 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
855 sLayerNameOne, sLayerNameOne,
856 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000857 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200858 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800859
860 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
861 surfaceFrame1->setRenderRate(renderRate);
862 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000863 presentFence1->signalForTest(90);
864 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800865
866 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000867 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200868
869 auto jankData = getLayerOneJankData();
870 EXPECT_EQ(jankData.size(), 1u);
871 EXPECT_EQ(jankData[0].jankType, JankType::AppDeadlineMissed);
Alec Mouri363faf02021-01-29 16:34:55 -0800872}
873
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000874TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200875 Fps refreshRate = RR_11;
876 Fps renderRate = RR_30;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000877
878 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000879 incrementJankyFrames(
880 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000881 sGameMode,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000882 JankType::Unknown | JankType::AppDeadlineMissed,
Adithya Srinivasande272452021-04-10 00:21:00 +0000883 0, 0, 25}));
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000884 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
885 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
886 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800887 FrameTimelineInfo ftInfo;
888 ftInfo.vsyncId = surfaceFrameToken1;
889 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000890
891 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800892 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
893 sLayerNameOne, sLayerNameOne,
894 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000895 surfaceFrame1->setAcquireFenceTime(45);
896 // Trigger a prediction expiry
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000897 flushTokens();
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200898 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000899
900 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
901 surfaceFrame1->setRenderRate(renderRate);
902 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
903 presentFence1->signalForTest(90);
904 mFrameTimeline->setSfPresent(86, presentFence1);
905
906 auto displayFrame = getDisplayFrame(0);
907 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +0000908 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000909 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
910 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
911 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
912
913 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000914 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000915 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200916
917 auto jankData = getLayerOneJankData();
918 EXPECT_EQ(jankData.size(), 1u);
919 EXPECT_EQ(jankData[0].jankType, JankType::Unknown | JankType::AppDeadlineMissed);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000920}
921
Adithya Srinivasan01189672020-10-20 14:23:05 -0700922/*
923 * Tracing Tests
924 *
925 * Trace packets are flushed all the way only when the next packet is traced.
926 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
927 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
928 * will have additional empty frames created for this reason.
929 */
930TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
931 auto tracingSession = getTracingSessionForTest();
932 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700933 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800934 FrameTimelineInfo ftInfo;
935 ftInfo.vsyncId = token1;
936 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000937 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800938 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
939 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000940 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700941
942 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200943 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800944 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
945 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700946 mFrameTimeline->setSfPresent(25, presentFence1);
947 presentFence1->signalForTest(30);
948
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000949 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700950
951 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000952 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700953}
954
955TEST_F(FrameTimelineTest, tracing_sanityTest) {
956 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800957 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800958 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700959 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700960
961 tracingSession->StartBlocking();
962 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
963 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800964 FrameTimelineInfo ftInfo;
965 ftInfo.vsyncId = token1;
966 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000967 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800968 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
969 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000970 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700971
972 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200973 mFrameTimeline->setSfWakeUp(token2, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800974 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
975 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700976 mFrameTimeline->setSfPresent(25, presentFence1);
977 presentFence1->signalForTest(30);
978
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000979 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000980 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700981 tracingSession->StopBlocking();
982
983 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000984 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000985 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700986}
987
988TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
989 auto tracingSession = getTracingSessionForTest();
990 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700991
992 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700993
994 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200995 mFrameTimeline->setSfWakeUp(-1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700996 mFrameTimeline->setSfPresent(25, presentFence1);
997 presentFence1->signalForTest(30);
998
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000999 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001000 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001001 tracingSession->StopBlocking();
1002
1003 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001004 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001005}
1006
1007TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
1008 auto tracingSession = getTracingSessionForTest();
1009 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001010
1011 tracingSession->StartBlocking();
1012 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -08001013 auto surfaceFrame1 =
1014 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001015 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001016 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001017
1018 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001019 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001020 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1021 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001022 mFrameTimeline->setSfPresent(25, presentFence1);
1023 presentFence1->signalForTest(30);
1024
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001025 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001026 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001027 tracingSession->StopBlocking();
1028
1029 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001030 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
1031 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001032 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001033}
1034
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001035ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
1036 pid_t pid) {
1037 ProtoExpectedDisplayFrameStart proto;
1038 proto.set_cookie(cookie);
1039 proto.set_token(token);
1040 proto.set_pid(pid);
1041 return proto;
1042}
1043
1044ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
1045 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Ying Wei96eb5352023-11-21 17:37:21 +00001046 bool gpuComposition, ProtoJankType jankType, ProtoJankSeverityType jankSeverityType,
1047 ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001048 ProtoActualDisplayFrameStart proto;
1049 proto.set_cookie(cookie);
1050 proto.set_token(token);
1051 proto.set_pid(pid);
1052 proto.set_present_type(presentType);
1053 proto.set_on_time_finish(onTimeFinish);
1054 proto.set_gpu_composition(gpuComposition);
1055 proto.set_jank_type(jankType);
Ying Wei96eb5352023-11-21 17:37:21 +00001056 proto.set_jank_severity_type(jankSeverityType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001057 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001058 return proto;
1059}
1060
1061ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
1062 int64_t displayFrameToken,
1063 pid_t pid,
1064 std::string layerName) {
1065 ProtoExpectedSurfaceFrameStart proto;
1066 proto.set_cookie(cookie);
1067 proto.set_token(token);
1068 proto.set_display_frame_token(displayFrameToken);
1069 proto.set_pid(pid);
1070 proto.set_layer_name(layerName);
1071 return proto;
1072}
1073
1074ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
1075 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
1076 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Ying Wei96eb5352023-11-21 17:37:21 +00001077 ProtoJankType jankType, ProtoJankSeverityType jankSeverityType,
1078 ProtoPredictionType predictionType, bool isBuffer) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001079 ProtoActualSurfaceFrameStart proto;
1080 proto.set_cookie(cookie);
1081 proto.set_token(token);
1082 proto.set_display_frame_token(displayFrameToken);
1083 proto.set_pid(pid);
1084 proto.set_layer_name(layerName);
1085 proto.set_present_type(presentType);
1086 proto.set_on_time_finish(onTimeFinish);
1087 proto.set_gpu_composition(gpuComposition);
1088 proto.set_jank_type(jankType);
Ying Wei96eb5352023-11-21 17:37:21 +00001089 proto.set_jank_severity_type(jankSeverityType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001090 proto.set_prediction_type(predictionType);
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001091 proto.set_is_buffer(isBuffer);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001092 return proto;
1093}
1094
1095ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
1096 ProtoFrameEnd proto;
1097 proto.set_cookie(cookie);
1098 return proto;
1099}
1100
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001101void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
1102 const ProtoExpectedDisplayFrameStart& source) {
1103 ASSERT_TRUE(received.has_cookie());
1104 EXPECT_EQ(received.cookie(), source.cookie());
1105
Adithya Srinivasan01189672020-10-20 14:23:05 -07001106 ASSERT_TRUE(received.has_token());
1107 EXPECT_EQ(received.token(), source.token());
1108
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001109 ASSERT_TRUE(received.has_pid());
1110 EXPECT_EQ(received.pid(), source.pid());
1111}
1112
1113void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
1114 const ProtoActualDisplayFrameStart& source) {
1115 ASSERT_TRUE(received.has_cookie());
1116 EXPECT_EQ(received.cookie(), source.cookie());
1117
1118 ASSERT_TRUE(received.has_token());
1119 EXPECT_EQ(received.token(), source.token());
1120
1121 ASSERT_TRUE(received.has_pid());
1122 EXPECT_EQ(received.pid(), source.pid());
1123
Adithya Srinivasan01189672020-10-20 14:23:05 -07001124 ASSERT_TRUE(received.has_present_type());
1125 EXPECT_EQ(received.present_type(), source.present_type());
1126 ASSERT_TRUE(received.has_on_time_finish());
1127 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1128 ASSERT_TRUE(received.has_gpu_composition());
1129 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1130 ASSERT_TRUE(received.has_jank_type());
1131 EXPECT_EQ(received.jank_type(), source.jank_type());
Ying Wei96eb5352023-11-21 17:37:21 +00001132 ASSERT_TRUE(received.has_jank_severity_type());
1133 EXPECT_EQ(received.jank_severity_type(), source.jank_severity_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001134 ASSERT_TRUE(received.has_prediction_type());
1135 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001136}
1137
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001138void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
1139 const ProtoExpectedSurfaceFrameStart& source) {
1140 ASSERT_TRUE(received.has_cookie());
1141 EXPECT_EQ(received.cookie(), source.cookie());
1142
Adithya Srinivasan01189672020-10-20 14:23:05 -07001143 ASSERT_TRUE(received.has_token());
1144 EXPECT_EQ(received.token(), source.token());
1145
1146 ASSERT_TRUE(received.has_display_frame_token());
1147 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1148
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001149 ASSERT_TRUE(received.has_pid());
1150 EXPECT_EQ(received.pid(), source.pid());
1151
1152 ASSERT_TRUE(received.has_layer_name());
1153 EXPECT_EQ(received.layer_name(), source.layer_name());
1154}
1155
1156void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
1157 const ProtoActualSurfaceFrameStart& source) {
1158 ASSERT_TRUE(received.has_cookie());
1159 EXPECT_EQ(received.cookie(), source.cookie());
1160
1161 ASSERT_TRUE(received.has_token());
1162 EXPECT_EQ(received.token(), source.token());
1163
1164 ASSERT_TRUE(received.has_display_frame_token());
1165 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1166
1167 ASSERT_TRUE(received.has_pid());
1168 EXPECT_EQ(received.pid(), source.pid());
1169
1170 ASSERT_TRUE(received.has_layer_name());
1171 EXPECT_EQ(received.layer_name(), source.layer_name());
1172
Adithya Srinivasan01189672020-10-20 14:23:05 -07001173 ASSERT_TRUE(received.has_present_type());
1174 EXPECT_EQ(received.present_type(), source.present_type());
1175 ASSERT_TRUE(received.has_on_time_finish());
1176 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1177 ASSERT_TRUE(received.has_gpu_composition());
1178 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1179 ASSERT_TRUE(received.has_jank_type());
1180 EXPECT_EQ(received.jank_type(), source.jank_type());
Ying Wei96eb5352023-11-21 17:37:21 +00001181 ASSERT_TRUE(received.has_jank_severity_type());
1182 EXPECT_EQ(received.jank_severity_type(), source.jank_severity_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001183 ASSERT_TRUE(received.has_prediction_type());
1184 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001185 ASSERT_TRUE(received.has_is_buffer());
1186 EXPECT_EQ(received.is_buffer(), source.is_buffer());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001187}
Adithya Srinivasan01189672020-10-20 14:23:05 -07001188
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001189void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
1190 ASSERT_TRUE(received.has_cookie());
1191 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001192}
1193
Sally Qi2269a692024-05-17 18:02:28 -07001194TEST_F(FrameTimelineTest, traceDisplayFrameNoSkipped) {
1195 // setup 2 display frames
1196 // DF 1: [22, 30] -> [0, 11]
1197 // DF 2: [82, 90] -> SF [5, 16]
1198 auto tracingSession = getTracingSessionForTest();
1199 tracingSession->StartBlocking();
1200 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1201 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 100});
1202 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({0, 11, 25});
1203 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1204 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1205
1206 int64_t traceCookie = snoopCurrentTraceCookie();
1207
1208 // set up 1st display frame
1209 FrameTimelineInfo ftInfo1;
1210 ftInfo1.vsyncId = surfaceFrameToken1;
1211 ftInfo1.inputEventId = sInputEventId;
1212 auto surfaceFrame1 =
1213 mFrameTimeline->createSurfaceFrameForToken(ftInfo1, sPidOne, sUidOne, sLayerIdOne,
1214 sLayerNameOne, sLayerNameOne,
1215 /*isBuffer*/ true, sGameMode);
1216 surfaceFrame1->setAcquireFenceTime(11);
1217 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_30);
1218 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1219 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1220 mFrameTimeline->setSfPresent(30, presentFence1);
1221 presentFence1->signalForTest(40);
1222
1223 // Trigger a flush by finalizing the next DisplayFrame
1224 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1225 FrameTimelineInfo ftInfo2;
1226 ftInfo2.vsyncId = surfaceFrameToken2;
1227 ftInfo2.inputEventId = sInputEventId;
1228 auto surfaceFrame2 =
1229 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1230 sLayerNameOne, sLayerNameOne,
1231 /*isBuffer*/ true, sGameMode);
1232
1233 // set up 2nd display frame
1234 surfaceFrame2->setAcquireFenceTime(16);
1235 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_11, RR_30);
1236 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1237 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1238 mFrameTimeline->setSfPresent(90, presentFence2);
1239 presentFence2->signalForTest(100);
1240
1241 // the token of skipped Display Frame
1242 auto protoSkippedActualDisplayFrameStart =
1243 createProtoActualDisplayFrameStart(traceCookie + 9, 0, kSurfaceFlingerPid,
1244 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1245 FrameTimelineEvent::JANK_DROPPED,
1246 FrameTimelineEvent::SEVERITY_NONE,
1247 FrameTimelineEvent::PREDICTION_VALID);
1248 auto protoSkippedActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 9);
1249
1250 // Trigger a flush by finalizing the next DisplayFrame
1251 addEmptyDisplayFrame();
1252 flushTrace();
1253 tracingSession->StopBlocking();
1254
1255 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1256 // 8 Valid Display Frames + 8 Valid Surface Frames + no Skipped Display Frames
1257 EXPECT_EQ(packets.size(), 16u);
1258}
1259
Sally Qiaa107742023-09-29 14:53:14 -07001260TEST_F(FrameTimelineTest, traceDisplayFrameSkipped) {
Sally Qif5721252023-11-17 11:14:53 -08001261 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::add_sf_skipped_frames_to_trace,
1262 true);
1263
Sally Qiaa107742023-09-29 14:53:14 -07001264 // setup 2 display frames
1265 // DF 1: [22,40] -> [5, 40]
1266 // DF : [36, 70] (Skipped one, added by the trace)
1267 // DF 2: [82, 100] -> SF [25, 70]
1268 auto tracingSession = getTracingSessionForTest();
1269 tracingSession->StartBlocking();
1270 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1271 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 100});
1272 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1273 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1274 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1275
1276 int64_t traceCookie = snoopCurrentTraceCookie();
1277
1278 // set up 1st display frame
1279 FrameTimelineInfo ftInfo1;
1280 ftInfo1.vsyncId = surfaceFrameToken1;
1281 ftInfo1.inputEventId = sInputEventId;
1282 auto surfaceFrame1 =
1283 mFrameTimeline->createSurfaceFrameForToken(ftInfo1, sPidOne, sUidOne, sLayerIdOne,
1284 sLayerNameOne, sLayerNameOne,
1285 /*isBuffer*/ true, sGameMode);
1286 surfaceFrame1->setAcquireFenceTime(16);
1287 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_30);
1288 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1289 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1290 mFrameTimeline->setSfPresent(30, presentFence1);
1291 presentFence1->signalForTest(40);
1292
1293 // Trigger a flush by finalizing the next DisplayFrame
1294 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1295 FrameTimelineInfo ftInfo2;
1296 ftInfo2.vsyncId = surfaceFrameToken2;
1297 ftInfo2.inputEventId = sInputEventId;
1298 auto surfaceFrame2 =
1299 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1300 sLayerNameOne, sLayerNameOne,
1301 /*isBuffer*/ true, sGameMode);
1302
1303 // set up 2nd display frame
1304 surfaceFrame2->setAcquireFenceTime(36);
1305 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_11, RR_30);
1306 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1307 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1308 mFrameTimeline->setSfPresent(90, presentFence2);
1309 presentFence2->signalForTest(100);
1310
1311 // the token of skipped Display Frame
1312 auto protoSkippedActualDisplayFrameStart =
1313 createProtoActualDisplayFrameStart(traceCookie + 9, 0, kSurfaceFlingerPid,
1314 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1315 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001316 FrameTimelineEvent::SEVERITY_NONE,
Sally Qiaa107742023-09-29 14:53:14 -07001317 FrameTimelineEvent::PREDICTION_VALID);
1318 auto protoSkippedActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 9);
1319
1320 // Trigger a flush by finalizing the next DisplayFrame
1321 addEmptyDisplayFrame();
1322 flushTrace();
1323 tracingSession->StopBlocking();
1324
1325 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1326 // 8 Valid Display Frames + 8 Valid Surface Frames + 2 Skipped Display Frames
1327 EXPECT_EQ(packets.size(), 18u);
1328
1329 // Packet - 16: Actual skipped Display Frame Start
1330 // the timestamp should be equal to the 2nd expected surface frame's end time
1331 const auto& packet16 = packets[16];
1332 ASSERT_TRUE(packet16.has_timestamp());
1333 EXPECT_EQ(packet16.timestamp(), 36u);
1334 ASSERT_TRUE(packet16.has_frame_timeline_event());
1335
1336 const auto& event16 = packet16.frame_timeline_event();
1337 const auto& actualSkippedDisplayFrameStart = event16.actual_display_frame_start();
1338 validateTraceEvent(actualSkippedDisplayFrameStart, protoSkippedActualDisplayFrameStart);
1339
1340 // Packet - 17: Actual skipped Display Frame End
1341 // the timestamp should be equal to the 2nd expected surface frame's present time
1342 const auto& packet17 = packets[17];
1343 ASSERT_TRUE(packet17.has_timestamp());
1344 EXPECT_EQ(packet17.timestamp(), 70u);
1345 ASSERT_TRUE(packet17.has_frame_timeline_event());
1346
1347 const auto& event17 = packet17.frame_timeline_event();
1348 const auto& actualSkippedDisplayFrameEnd = event17.frame_end();
1349 validateTraceEvent(actualSkippedDisplayFrameEnd, protoSkippedActualDisplayFrameEnd);
1350}
1351
Adithya Srinivasan01189672020-10-20 14:23:05 -07001352TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
1353 auto tracingSession = getTracingSessionForTest();
1354 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001355
1356 tracingSession->StartBlocking();
Ady Abraham57a8ab42023-01-26 15:28:19 -08001357
1358 // Add an empty surface frame so that display frame would get traced.
1359 addEmptySurfaceFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001360 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001361
1362 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001363 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001364 mFrameTimeline->setSfPresent(26, presentFence1);
1365 presentFence1->signalForTest(31);
1366
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001367 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001368 auto protoExpectedDisplayFrameStart =
1369 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1370 kSurfaceFlingerPid);
1371 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1372 auto protoActualDisplayFrameStart =
1373 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
1374 kSurfaceFlingerPid,
1375 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001376 FrameTimelineEvent::JANK_NONE,
Ying Wei96eb5352023-11-21 17:37:21 +00001377 FrameTimelineEvent::SEVERITY_NONE,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001378 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001379 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001380
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001381 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001382 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001383 tracingSession->StopBlocking();
1384
1385 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001386 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001387
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001388 // Packet - 0 : ExpectedDisplayFrameStart
1389 const auto& packet0 = packets[0];
1390 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001391 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001392 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001393
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001394 const auto& event0 = packet0.frame_timeline_event();
1395 ASSERT_TRUE(event0.has_expected_display_frame_start());
1396 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
1397 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
1398
1399 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
1400 const auto& packet1 = packets[1];
1401 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001402 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001403 ASSERT_TRUE(packet1.has_frame_timeline_event());
1404
1405 const auto& event1 = packet1.frame_timeline_event();
1406 ASSERT_TRUE(event1.has_frame_end());
1407 const auto& expectedDisplayFrameEnd = event1.frame_end();
1408 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
1409
1410 // Packet - 2 : ActualDisplayFrameStart
1411 const auto& packet2 = packets[2];
1412 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001413 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001414 ASSERT_TRUE(packet2.has_frame_timeline_event());
1415
1416 const auto& event2 = packet2.frame_timeline_event();
1417 ASSERT_TRUE(event2.has_actual_display_frame_start());
1418 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1419 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1420
1421 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1422 const auto& packet3 = packets[3];
1423 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001424 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001425 ASSERT_TRUE(packet3.has_frame_timeline_event());
1426
1427 const auto& event3 = packet3.frame_timeline_event();
1428 ASSERT_TRUE(event3.has_frame_end());
1429 const auto& actualDisplayFrameEnd = event3.frame_end();
1430 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001431}
1432
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001433TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1434 auto tracingSession = getTracingSessionForTest();
1435 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1436
1437 tracingSession->StartBlocking();
1438 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1439 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001440 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001441
Ady Abraham57a8ab42023-01-26 15:28:19 -08001442 // Add an empty surface frame so that display frame would get traced.
1443 addEmptySurfaceFrame();
1444
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001445 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001446 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001447 mFrameTimeline->setSfPresent(26, presentFence1);
1448 presentFence1->signalForTest(31);
1449
1450 int64_t traceCookie = snoopCurrentTraceCookie();
1451
1452 auto protoActualDisplayFrameStart =
1453 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1454 kSurfaceFlingerPid,
1455 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001456 false, FrameTimelineEvent::JANK_UNKNOWN,
Ying Wei96eb5352023-11-21 17:37:21 +00001457 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001458 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001459 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1460
1461 addEmptyDisplayFrame();
1462 flushTrace();
1463 tracingSession->StopBlocking();
1464
1465 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1466 // Only actual timeline packets should be in the trace
1467 EXPECT_EQ(packets.size(), 2u);
1468
1469 // Packet - 0 : ActualDisplayFrameStart
1470 const auto& packet0 = packets[0];
1471 ASSERT_TRUE(packet0.has_timestamp());
1472 EXPECT_EQ(packet0.timestamp(), 20u);
1473 ASSERT_TRUE(packet0.has_frame_timeline_event());
1474
1475 const auto& event0 = packet0.frame_timeline_event();
1476 ASSERT_TRUE(event0.has_actual_display_frame_start());
1477 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1478 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1479
1480 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1481 const auto& packet1 = packets[1];
1482 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001483 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001484 ASSERT_TRUE(packet1.has_frame_timeline_event());
1485
1486 const auto& event1 = packet1.frame_timeline_event();
1487 ASSERT_TRUE(event1.has_frame_end());
1488 const auto& actualDisplayFrameEnd = event1.frame_end();
1489 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1490}
1491
Adithya Srinivasan01189672020-10-20 14:23:05 -07001492TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1493 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001494 // Layer specific increment
Edgar Arriaga631e4252023-03-02 02:11:24 +00001495 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001496 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1497 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1498
1499 tracingSession->StartBlocking();
1500 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1501 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001502
Huihong Luo3bdef862022-03-03 11:57:19 -08001503 FrameTimelineInfo ftInfo;
1504 ftInfo.vsyncId = surfaceFrameToken;
1505 ftInfo.inputEventId = sInputEventId;
1506
Adithya Srinivasan01189672020-10-20 14:23:05 -07001507 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001508 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1509 sLayerNameOne, sLayerNameOne,
1510 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001511 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001512 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1513 sLayerNameOne, sLayerNameOne,
1514 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001515 surfaceFrame1->setActualQueueTime(10);
1516 surfaceFrame1->setDropTime(15);
1517
1518 surfaceFrame2->setActualQueueTime(15);
1519 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001520
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001521 // First 2 cookies will be used by the DisplayFrame
1522 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1523
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001524 auto protoDroppedSurfaceFrameExpectedStart =
1525 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1526 displayFrameToken1, sPidOne, sLayerNameOne);
1527 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1528 auto protoDroppedSurfaceFrameActualStart =
1529 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1530 displayFrameToken1, sPidOne, sLayerNameOne,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001531 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1532 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001533 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001534 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001535 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001536
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001537 auto protoPresentedSurfaceFrameExpectedStart =
1538 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1539 displayFrameToken1, sPidOne, sLayerNameOne);
1540 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1541 auto protoPresentedSurfaceFrameActualStart =
1542 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1543 displayFrameToken1, sPidOne, sLayerNameOne,
1544 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001545 FrameTimelineEvent::JANK_NONE,
Ying Wei96eb5352023-11-21 17:37:21 +00001546 FrameTimelineEvent::SEVERITY_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001547 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001548 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001549
1550 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001551 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001552 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1553 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001554 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001555 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001556 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001557 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001558
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001559 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001560 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001561 tracingSession->StopBlocking();
1562
1563 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001564 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1565 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001566
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001567 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001568 const auto& packet4 = packets[4];
1569 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001570 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001571 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001572
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001573 const auto& event4 = packet4.frame_timeline_event();
1574 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001575 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1576 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001577
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001578 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001579 const auto& packet5 = packets[5];
1580 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001581 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001582 ASSERT_TRUE(packet5.has_frame_timeline_event());
1583
1584 const auto& event5 = packet5.frame_timeline_event();
1585 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001586 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1587 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001588
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001589 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001590 const auto& packet6 = packets[6];
1591 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001592 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001593 ASSERT_TRUE(packet6.has_frame_timeline_event());
1594
1595 const auto& event6 = packet6.frame_timeline_event();
1596 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001597 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1598 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001599
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001600 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001601 const auto& packet7 = packets[7];
1602 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001603 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001604 ASSERT_TRUE(packet7.has_frame_timeline_event());
1605
1606 const auto& event7 = packet7.frame_timeline_event();
1607 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001608 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1609 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1610
1611 // Packet - 8 : ExpectedSurfaceFrameStart2
1612 const auto& packet8 = packets[8];
1613 ASSERT_TRUE(packet8.has_timestamp());
1614 EXPECT_EQ(packet8.timestamp(), 10u);
1615 ASSERT_TRUE(packet8.has_frame_timeline_event());
1616
1617 const auto& event8 = packet8.frame_timeline_event();
1618 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1619 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1620 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1621
1622 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1623 const auto& packet9 = packets[9];
1624 ASSERT_TRUE(packet9.has_timestamp());
1625 EXPECT_EQ(packet9.timestamp(), 25u);
1626 ASSERT_TRUE(packet9.has_frame_timeline_event());
1627
1628 const auto& event9 = packet9.frame_timeline_event();
1629 ASSERT_TRUE(event9.has_frame_end());
1630 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1631 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1632
1633 // Packet - 10 : ActualSurfaceFrameStart2
1634 const auto& packet10 = packets[10];
1635 ASSERT_TRUE(packet10.has_timestamp());
1636 EXPECT_EQ(packet10.timestamp(), 10u);
1637 ASSERT_TRUE(packet10.has_frame_timeline_event());
1638
1639 const auto& event10 = packet10.frame_timeline_event();
1640 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1641 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1642 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1643
1644 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1645 const auto& packet11 = packets[11];
1646 ASSERT_TRUE(packet11.has_timestamp());
1647 EXPECT_EQ(packet11.timestamp(), 20u);
1648 ASSERT_TRUE(packet11.has_frame_timeline_event());
1649
1650 const auto& event11 = packet11.frame_timeline_event();
1651 ASSERT_TRUE(event11.has_frame_end());
1652 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1653 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1654}
1655
Ady Abrahame43ff722022-02-15 14:44:25 -08001656TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredIsAppMissedDeadline) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001657 auto tracingSession = getTracingSessionForTest();
1658 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1659
1660 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001661 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1662 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1663 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001664 int64_t surfaceFrameToken =
1665 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1666
1667 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001668 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001669 FrameTimelineInfo ftInfo;
1670 ftInfo.vsyncId = surfaceFrameToken;
1671 ftInfo.inputEventId = 0;
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001672 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001673 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1674 sLayerNameOne, sLayerNameOne,
1675 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001676 surfaceFrame1->setActualQueueTime(appEndTime);
1677 surfaceFrame1->setAcquireFenceTime(appEndTime);
1678
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001679 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1680 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1681 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001682 int64_t displayFrameToken =
1683 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1684
1685 // First 2 cookies will be used by the DisplayFrame
1686 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1687
1688 auto protoActualSurfaceFrameStart =
1689 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1690 displayFrameToken, sPidOne, sLayerNameOne,
1691 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Ady Abrahame43ff722022-02-15 14:44:25 -08001692 false, FrameTimelineEvent::JANK_APP_DEADLINE_MISSED,
Ying Wei96eb5352023-11-21 17:37:21 +00001693 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001694 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001695 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1696
1697 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001698 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001699 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1700 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1701 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1702 presentFence1->signalForTest(sfPresentTime);
1703
1704 addEmptyDisplayFrame();
1705 flushTrace();
1706 tracingSession->StopBlocking();
1707
1708 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1709 // Display Frame 4 packets + SurfaceFrame 2 packets
1710 ASSERT_EQ(packets.size(), 6u);
1711
1712 // Packet - 4 : ActualSurfaceFrameStart
1713 const auto& packet4 = packets[4];
1714 ASSERT_TRUE(packet4.has_timestamp());
1715 EXPECT_EQ(packet4.timestamp(),
1716 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1717 ASSERT_TRUE(packet4.has_frame_timeline_event());
1718
1719 const auto& event4 = packet4.frame_timeline_event();
1720 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1721 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1722 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1723
1724 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1725 const auto& packet5 = packets[5];
1726 ASSERT_TRUE(packet5.has_timestamp());
1727 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1728 ASSERT_TRUE(packet5.has_frame_timeline_event());
1729
1730 const auto& event5 = packet5.frame_timeline_event();
1731 ASSERT_TRUE(event5.has_frame_end());
1732 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001733 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001734}
1735
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001736TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDroppedFramesTracedProperly) {
1737 auto tracingSession = getTracingSessionForTest();
1738 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1739
1740 tracingSession->StartBlocking();
1741 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1742 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1743 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
1744 int64_t surfaceFrameToken =
1745 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1746
1747 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001748 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001749 FrameTimelineInfo ftInfo;
1750 ftInfo.vsyncId = surfaceFrameToken;
1751 ftInfo.inputEventId = 0;
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001752 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001753 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1754 sLayerNameOne, sLayerNameOne,
1755 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001756
1757 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(22ms).count();
1758 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1759 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
1760 int64_t displayFrameToken =
1761 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1762
1763 // First 2 cookies will be used by the DisplayFrame
1764 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1765
1766 auto protoActualSurfaceFrameStart =
1767 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1768 displayFrameToken, sPidOne, sLayerNameOne,
1769 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001770 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001771 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001772 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001773 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1774
1775 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001776 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001777 surfaceFrame1->setDropTime(sfStartTime);
1778 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1779 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1780 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1781 presentFence1->signalForTest(sfPresentTime);
1782
1783 addEmptyDisplayFrame();
1784 flushTrace();
1785 tracingSession->StopBlocking();
1786
1787 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1788 // Display Frame 4 packets + SurfaceFrame 2 packets
1789 ASSERT_EQ(packets.size(), 6u);
1790
1791 // Packet - 4 : ActualSurfaceFrameStart
1792 const auto& packet4 = packets[4];
1793 ASSERT_TRUE(packet4.has_timestamp());
1794 EXPECT_EQ(packet4.timestamp(),
1795 static_cast<uint64_t>(sfStartTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1796 ASSERT_TRUE(packet4.has_frame_timeline_event());
1797
1798 const auto& event4 = packet4.frame_timeline_event();
1799 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1800 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1801 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1802
1803 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1804 const auto& packet5 = packets[5];
1805 ASSERT_TRUE(packet5.has_timestamp());
1806 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(sfStartTime));
1807 ASSERT_TRUE(packet5.has_frame_timeline_event());
1808
1809 const auto& event5 = packet5.frame_timeline_event();
1810 ASSERT_TRUE(event5.has_frame_end());
1811 const auto& actualSurfaceFrameEnd = event5.frame_end();
1812 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
1813}
1814
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001815// Tests for Jank classification
1816TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001817 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001818 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001819 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1820 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001821 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -08001822 FrameTimelineInfo ftInfo;
1823 ftInfo.vsyncId = surfaceFrameToken;
1824 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001825 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -08001826 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1827 sLayerNameOne, sLayerNameOne,
1828 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001829 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001830 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1831 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1832 mFrameTimeline->setSfPresent(26, presentFence1);
1833 auto displayFrame = getDisplayFrame(0);
1834 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1835 presentFence1->signalForTest(29);
1836
1837 // Fences haven't been flushed yet, so it should be 0
1838 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1839 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1840
1841 addEmptyDisplayFrame();
1842 displayFrame = getDisplayFrame(0);
1843
1844 // Fences have flushed, so the present timestamps should be updated
1845 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1846 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1847 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1848 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1849 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00001850 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::None);
Pascal Mütschardd56514e2024-05-24 17:37:13 +02001851
1852 auto jankData = getLayerOneJankData();
1853 EXPECT_EQ(jankData.size(), 1u);
1854 EXPECT_EQ(jankData[0].jankType, JankType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001855}
1856
1857TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001858 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001859 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001860 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1861 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001862 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001863 mFrameTimeline->setSfPresent(26, presentFence1);
1864 auto displayFrame = getDisplayFrame(0);
1865 presentFence1->signalForTest(30);
1866
1867 // Fences for the first frame haven't been flushed yet, so it should be 0
1868 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1869
1870 // Trigger a flush by finalizing the next DisplayFrame
1871 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001872 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001873 mFrameTimeline->setSfPresent(56, presentFence2);
1874 displayFrame = getDisplayFrame(0);
1875
1876 // Fences for the first frame have flushed, so the present timestamps should be updated
1877 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1878 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1879 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1880 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00001881 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001882
1883 // Fences for the second frame haven't been flushed yet, so it should be 0
1884 auto displayFrame2 = getDisplayFrame(1);
1885 presentFence2->signalForTest(65);
1886 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001887 addEmptyDisplayFrame();
1888 displayFrame2 = getDisplayFrame(1);
1889
1890 // Fences for the second frame have flushed, so the present timestamps should be updated
1891 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1892 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1893 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1894 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00001895 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001896}
1897
1898TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001899 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001900 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001901 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1902 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001903 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001904 mFrameTimeline->setSfPresent(26, presentFence1);
1905 auto displayFrame = getDisplayFrame(0);
1906 presentFence1->signalForTest(50);
1907
1908 // Fences for the first frame haven't been flushed yet, so it should be 0
1909 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1910
1911 // Trigger a flush by finalizing the next DisplayFrame
1912 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001913 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001914 mFrameTimeline->setSfPresent(56, presentFence2);
1915 displayFrame = getDisplayFrame(0);
1916
1917 // Fences for the first frame have flushed, so the present timestamps should be updated
1918 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1919 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1920 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1921 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00001922 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001923
1924 // Fences for the second frame haven't been flushed yet, so it should be 0
1925 auto displayFrame2 = getDisplayFrame(1);
1926 presentFence2->signalForTest(75);
1927 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1928
1929 addEmptyDisplayFrame();
1930 displayFrame2 = getDisplayFrame(1);
1931
1932 // Fences for the second frame have flushed, so the present timestamps should be updated
1933 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1934 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1935 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1936 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00001937 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001938}
1939
1940TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001941 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1942 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001943 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001944
1945 mFrameTimeline->setSfPresent(22, presentFence1);
1946 auto displayFrame = getDisplayFrame(0);
1947 presentFence1->signalForTest(28);
1948
1949 // Fences haven't been flushed yet, so it should be 0
1950 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1951
1952 addEmptyDisplayFrame();
1953 displayFrame = getDisplayFrame(0);
1954
1955 // Fences have flushed, so the present timestamps should be updated
1956 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1957 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1958 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1959 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00001960 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001961}
1962
1963TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001964 /*
1965 * Case 1 - cpu time > vsync period but combined time > deadline > deadline -> cpudeadlinemissed
1966 * Case 2 - cpu time < vsync period but combined time > deadline -> gpudeadlinemissed
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001967 * Case 3 - previous frame ran longer -> sf_stuffing
1968 * Case 4 - Long cpu under SF stuffing -> cpudeadlinemissed
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001969 */
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001970 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001971 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001972 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1973 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001974 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1975 auto gpuFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001976 auto gpuFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1977 auto gpuFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001978 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001979 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001980 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1981 int64_t sfToken4 = mTokenManager->generateTokenForPredictions({112, 120, 120});
1982
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001983 // case 1 - cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001984 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001985 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
1986 auto displayFrame0 = getDisplayFrame(0);
1987 gpuFence1->signalForTest(36);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001988 presentFence1->signalForTest(52);
1989
1990 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001991 EXPECT_EQ(displayFrame0->getActuals().presentTime, 0);
1992
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001993 // case 2 - cpu time = 56 - 52 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001994 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001995 mFrameTimeline->setSfPresent(56, presentFence2, gpuFence2);
1996 auto displayFrame1 = getDisplayFrame(1);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001997 gpuFence2->signalForTest(76);
1998 presentFence2->signalForTest(90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001999
2000 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2001 // Fences have flushed for first displayFrame, so the present timestamps should be updated
2002 EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
2003 EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2004 EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Rachel Lee94917b32022-03-18 17:52:09 -07002005 EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002006 EXPECT_EQ(displayFrame0->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002007
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002008 // case 3 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002009 mFrameTimeline->setSfWakeUp(sfToken3, 106, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002010 mFrameTimeline->setSfPresent(112, presentFence3, gpuFence3);
2011 auto displayFrame2 = getDisplayFrame(2);
2012 gpuFence3->signalForTest(116);
2013 presentFence3->signalForTest(120);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002014
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002015 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00002016 // Fences have flushed for second displayFrame, so the present timestamps should be updated
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002017 EXPECT_EQ(displayFrame1->getActuals().presentTime, 90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00002018 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2019 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2020 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002021 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002022
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002023 // case 4 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002024 mFrameTimeline->setSfWakeUp(sfToken4, 120, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002025 mFrameTimeline->setSfPresent(140, presentFence4, gpuFence4);
2026 auto displayFrame3 = getDisplayFrame(3);
2027 gpuFence4->signalForTest(156);
2028 presentFence4->signalForTest(180);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002029
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002030 EXPECT_EQ(displayFrame3->getActuals().presentTime, 0);
2031 // Fences have flushed for third displayFrame, so the present timestamps should be updated
2032 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
2033 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2034 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2035 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00002036 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002037
2038 addEmptyDisplayFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002039
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002040 // Fences have flushed for third displayFrame, so the present timestamps should be updated
2041 EXPECT_EQ(displayFrame3->getActuals().presentTime, 180);
2042 EXPECT_EQ(displayFrame3->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2043 EXPECT_EQ(displayFrame3->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2044 EXPECT_EQ(displayFrame3->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002045 EXPECT_EQ(displayFrame3->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002046}
2047
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002048TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08002049 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002050 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002051 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
2052 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002053 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
2054 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08002055 FrameTimelineInfo ftInfo;
2056 ftInfo.vsyncId = surfaceFrameToken1;
2057 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002058 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002059 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2060 sLayerNameOne, sLayerNameOne,
2061 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002062 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002063 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002064 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2065 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002066 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002067 auto displayFrame1 = getDisplayFrame(0);
2068 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2069 presentFence1->signalForTest(30);
2070
2071 // Fences for the first frame haven't been flushed yet, so it should be 0
2072 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2073 auto actuals1 = presentedSurfaceFrame1.getActuals();
2074 EXPECT_EQ(actuals1.presentTime, 0);
2075
2076 // Trigger a flush by finalizing the next DisplayFrame
2077 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002078 FrameTimelineInfo ftInfo2;
2079 ftInfo2.vsyncId = surfaceFrameToken2;
2080 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002081 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002082 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2083 sLayerNameOne, sLayerNameOne,
2084 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002085 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002086 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002087 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2088 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002089 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002090 auto displayFrame2 = getDisplayFrame(1);
2091 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2092
2093 // Fences for the first frame have flushed, so the present timestamps should be updated
2094 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
2095 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2096 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2097 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00002098 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002099
2100 actuals1 = presentedSurfaceFrame1.getActuals();
2101 EXPECT_EQ(actuals1.presentTime, 30);
2102 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2103 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2104 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00002105 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002106
2107 // Fences for the second frame haven't been flushed yet, so it should be 0
2108 presentFence2->signalForTest(65);
2109 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2110 auto actuals2 = presentedSurfaceFrame2.getActuals();
2111 EXPECT_EQ(actuals2.presentTime, 0);
2112
Alec Mouri363faf02021-01-29 16:34:55 -08002113 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
2114
2115 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002116 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
2117 sLayerNameOne, sGameMode,
2118 JankType::PredictionError, -3, 5,
2119 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08002120
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002121 addEmptyDisplayFrame();
2122
2123 // Fences for the second frame have flushed, so the present timestamps should be updated
2124 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
2125 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2126 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2127 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002128 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002129
2130 actuals2 = presentedSurfaceFrame2.getActuals();
2131 EXPECT_EQ(actuals2.presentTime, 65);
2132 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2133 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2134 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002135 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002136}
2137
2138TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08002139 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002140 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002141 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
2142 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002143 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
2144 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08002145 FrameTimelineInfo ftInfo;
2146 ftInfo.vsyncId = surfaceFrameToken1;
2147 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002148 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002149 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2150 sLayerNameOne, sLayerNameOne,
2151 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002152 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002153 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002154 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2155 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2156 mFrameTimeline->setSfPresent(26, presentFence1);
2157 auto displayFrame1 = getDisplayFrame(0);
2158 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2159 presentFence1->signalForTest(50);
2160
2161 // Fences for the first frame haven't been flushed yet, so it should be 0
2162 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2163 auto actuals1 = presentedSurfaceFrame1.getActuals();
2164 EXPECT_EQ(actuals1.presentTime, 0);
2165
2166 // Trigger a flush by finalizing the next DisplayFrame
2167 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002168 FrameTimelineInfo ftInfo2;
2169 ftInfo2.vsyncId = surfaceFrameToken2;
2170 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002171 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002172 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2173 sLayerNameOne, sLayerNameOne,
2174 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002175 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002176 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002177 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2178 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002179 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002180 auto displayFrame2 = getDisplayFrame(1);
2181 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2182
2183 // Fences for the first frame have flushed, so the present timestamps should be updated
2184 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
2185 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2186 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2187 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002188 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002189
2190 actuals1 = presentedSurfaceFrame1.getActuals();
2191 EXPECT_EQ(actuals1.presentTime, 50);
2192 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2193 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2194 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002195 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002196
2197 // Fences for the second frame haven't been flushed yet, so it should be 0
2198 presentFence2->signalForTest(86);
2199 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2200 auto actuals2 = presentedSurfaceFrame2.getActuals();
2201 EXPECT_EQ(actuals2.presentTime, 0);
2202
Alec Mouri363faf02021-01-29 16:34:55 -08002203 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
2204
2205 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002206 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
2207 sLayerNameOne, sGameMode,
2208 JankType::PredictionError, -3, 5,
2209 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08002210
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002211 addEmptyDisplayFrame();
2212
2213 // Fences for the second frame have flushed, so the present timestamps should be updated
2214 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
2215 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2216 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2217 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002218 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002219
2220 actuals2 = presentedSurfaceFrame2.getActuals();
2221 EXPECT_EQ(actuals2.presentTime, 86);
2222 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2223 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2224 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002225 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002226}
2227
2228TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08002229 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08002230
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002231 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002232 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002233 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -08002234 FrameTimelineInfo ftInfo;
2235 ftInfo.vsyncId = surfaceFrameToken1;
2236 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002237 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002238 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2239 sLayerNameOne, sLayerNameOne,
2240 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002241 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002242 mFrameTimeline->setSfWakeUp(sfToken1, 42, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002243 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2244 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2245 mFrameTimeline->setSfPresent(46, presentFence1);
2246 auto displayFrame1 = getDisplayFrame(0);
2247 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2248 presentFence1->signalForTest(50);
2249
2250 // Fences for the first frame haven't been flushed yet, so it should be 0
2251 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2252 auto actuals1 = presentedSurfaceFrame1.getActuals();
2253 EXPECT_EQ(actuals1.presentTime, 0);
2254
2255 addEmptyDisplayFrame();
2256
2257 // Fences for the first frame have flushed, so the present timestamps should be updated
2258 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
2259 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2260 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2261 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002262 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002263
2264 actuals1 = presentedSurfaceFrame1.getActuals();
2265 EXPECT_EQ(actuals1.presentTime, 50);
2266 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2267 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2268 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +00002269 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002270}
2271
2272TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002273 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as only
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002274 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002275 // jank to the SurfaceFrame along with AppDeadlineMissed.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002276
Alec Mouri363faf02021-01-29 16:34:55 -08002277 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002278 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002279 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
2280 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002281 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
2282 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
Huihong Luo3bdef862022-03-03 11:57:19 -08002283 FrameTimelineInfo ftInfo;
2284 ftInfo.vsyncId = surfaceFrameToken1;
2285 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002286 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002287 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2288 sLayerNameOne, sLayerNameOne,
2289 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002290 surfaceFrame1->setAcquireFenceTime(26);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002291 mFrameTimeline->setSfWakeUp(sfToken1, 32, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002292 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2293 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2294 mFrameTimeline->setSfPresent(36, presentFence1);
2295 auto displayFrame1 = getDisplayFrame(0);
2296 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2297 presentFence1->signalForTest(40);
2298
2299 // Fences for the first frame haven't been flushed yet, so it should be 0
2300 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2301 auto actuals1 = presentedSurfaceFrame1.getActuals();
2302 EXPECT_EQ(actuals1.presentTime, 0);
2303
2304 // Trigger a flush by finalizing the next DisplayFrame
2305 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002306 FrameTimelineInfo ftInfo2;
2307 ftInfo2.vsyncId = surfaceFrameToken2;
2308 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002309 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002310 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2311 sLayerNameOne, sLayerNameOne,
2312 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002313 surfaceFrame2->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002314 mFrameTimeline->setSfWakeUp(sfToken2, 43, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002315 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2316 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2317 mFrameTimeline->setSfPresent(56, presentFence2);
2318 auto displayFrame2 = getDisplayFrame(1);
2319 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2320
2321 // Fences for the first frame have flushed, so the present timestamps should be updated
2322 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
2323 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2324 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2325 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002326 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002327
2328 actuals1 = presentedSurfaceFrame1.getActuals();
2329 EXPECT_EQ(actuals1.presentTime, 40);
2330 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2331 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2332 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002333 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002334
2335 // Fences for the second frame haven't been flushed yet, so it should be 0
2336 presentFence2->signalForTest(60);
2337 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2338 auto actuals2 = presentedSurfaceFrame2.getActuals();
2339 EXPECT_EQ(actuals2.presentTime, 0);
2340
2341 addEmptyDisplayFrame();
2342
2343 // Fences for the second frame have flushed, so the present timestamps should be updated
2344 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
2345 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2346 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2347 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002348 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002349
2350 actuals2 = presentedSurfaceFrame2.getActuals();
2351 EXPECT_EQ(actuals2.presentTime, 60);
2352 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2353 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002354 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2355 JankType::SurfaceFlingerCpuDeadlineMissed | JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002356 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002357}
2358
2359TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002360 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08002361 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002362 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2363 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2364 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2365
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002366 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2367 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Huihong Luo3bdef862022-03-03 11:57:19 -08002368 FrameTimelineInfo ftInfo;
2369 ftInfo.vsyncId = surfaceFrameToken1;
2370 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002371 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002372 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2373 sLayerNameOne, sLayerNameOne,
2374 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002375 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002376 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002377 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2378 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2379 mFrameTimeline->setSfPresent(56, presentFence1);
2380 auto displayFrame1 = getDisplayFrame(0);
2381 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2382 presentFence1->signalForTest(60);
2383
2384 // Fences for the first frame haven't been flushed yet, so it should be 0
2385 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2386 auto actuals1 = presentedSurfaceFrame1.getActuals();
2387 EXPECT_EQ(actuals1.presentTime, 0);
2388
2389 // Trigger a flush by finalizing the next DisplayFrame
2390 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002391 FrameTimelineInfo ftInfo2;
2392 ftInfo2.vsyncId = surfaceFrameToken2;
2393 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002394 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002395 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2396 sLayerNameOne, sLayerNameOne,
2397 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002398 surfaceFrame2->setAcquireFenceTime(84);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002399 mFrameTimeline->setSfWakeUp(sfToken2, 112, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002400 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2401 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2402 mFrameTimeline->setSfPresent(116, presentFence2);
2403 auto displayFrame2 = getDisplayFrame(1);
2404 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2405 presentFence2->signalForTest(120);
2406
2407 // Fences for the first frame have flushed, so the present timestamps should be updated
2408 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2409 actuals1 = presentedSurfaceFrame1.getActuals();
2410 EXPECT_EQ(actuals1.endTime, 50);
2411 EXPECT_EQ(actuals1.presentTime, 60);
2412
2413 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2414 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2415 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002416 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002417
2418 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2419 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2420 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002421 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002422
2423 // Fences for the second frame haven't been flushed yet, so it should be 0
2424 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2425 auto actuals2 = presentedSurfaceFrame2.getActuals();
2426 EXPECT_EQ(actuals2.presentTime, 0);
2427
2428 addEmptyDisplayFrame();
2429
2430 // Fences for the second frame have flushed, so the present timestamps should be updated
2431 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
2432 actuals2 = presentedSurfaceFrame2.getActuals();
2433 EXPECT_EQ(actuals2.presentTime, 120);
2434
2435 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2436 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2437 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002438 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002439
2440 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2441 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2442 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2443 JankType::AppDeadlineMissed | JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00002444 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002445}
Alec Mouriadebf5c2021-01-05 12:57:36 -08002446
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002447TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
2448 // Layer specific increment
2449 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
2450 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2451 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2452 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2453
2454 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2455 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -08002456 FrameTimelineInfo ftInfo;
2457 ftInfo.vsyncId = surfaceFrameToken1;
2458 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002459 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002460 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2461 sLayerNameOne, sLayerNameOne,
2462 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002463 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002464 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002465 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2466 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2467 mFrameTimeline->setSfPresent(56, presentFence1);
2468 auto displayFrame1 = getDisplayFrame(0);
2469 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2470 presentFence1->signalForTest(60);
2471
2472 // Fences for the first frame haven't been flushed yet, so it should be 0
2473 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2474 auto actuals1 = presentedSurfaceFrame1.getActuals();
2475 EXPECT_EQ(actuals1.presentTime, 0);
2476
2477 // Trigger a flush by finalizing the next DisplayFrame
2478 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002479 FrameTimelineInfo ftInfo2;
2480 ftInfo2.vsyncId = surfaceFrameToken2;
2481 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002482 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002483 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2484 sLayerNameOne, sLayerNameOne,
2485 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002486 surfaceFrame2->setAcquireFenceTime(80);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002487 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002488 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
2489 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2490 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2491 mFrameTimeline->setSfPresent(86, presentFence2);
2492 auto displayFrame2 = getDisplayFrame(1);
2493 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2494 presentFence2->signalForTest(90);
2495
2496 // Fences for the first frame have flushed, so the present timestamps should be updated
2497 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2498 actuals1 = presentedSurfaceFrame1.getActuals();
2499 EXPECT_EQ(actuals1.endTime, 50);
2500 EXPECT_EQ(actuals1.presentTime, 60);
2501
2502 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2503 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2504 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002505 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002506
2507 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2508 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2509 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002510 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002511
2512 // Fences for the second frame haven't been flushed yet, so it should be 0
2513 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2514 auto actuals2 = presentedSurfaceFrame2.getActuals();
2515 EXPECT_EQ(actuals2.presentTime, 0);
2516
2517 addEmptyDisplayFrame();
2518
2519 // Fences for the second frame have flushed, so the present timestamps should be updated
2520 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2521 actuals2 = presentedSurfaceFrame2.getActuals();
2522 EXPECT_EQ(actuals2.presentTime, 90);
2523
2524 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2525 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2526 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002527 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002528
2529 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2530 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2531 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00002532 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002533}
2534
Rachel Lee94917b32022-03-18 17:52:09 -07002535TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent_GpuAndCpuMiss) {
2536 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2537 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2538 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2539 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2540 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2541
2542 // Case 1: cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002543 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Rachel Lee94917b32022-03-18 17:52:09 -07002544 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
2545 auto displayFrame = getDisplayFrame(0);
2546 gpuFence1->signalForTest(36);
2547 presentFence1->signalForTest(52);
2548
2549 // Fences haven't been flushed yet, so it should be 0
2550 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
2551
2552 addEmptyDisplayFrame();
2553 displayFrame = getDisplayFrame(0);
2554
2555 // Fences have flushed, so the present timestamps should be updated
2556 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
2557 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2558 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2559 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002560 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Full);
Rachel Lee94917b32022-03-18 17:52:09 -07002561
2562 // Case 2: No GPU fence so it will not use GPU composition.
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002563 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Rachel Lee94917b32022-03-18 17:52:09 -07002564 mFrameTimeline->setSfPresent(66, presentFence2);
2565 auto displayFrame2 = getDisplayFrame(2); // 2 because of previous empty frame
2566 presentFence2->signalForTest(90);
2567
2568 // Fences for the frame haven't been flushed yet, so it should be 0
2569 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2570
2571 addEmptyDisplayFrame();
2572
2573 // Fences have flushed, so the present timestamps should be updated
2574 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2575 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2576 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2577 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002578 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Rachel Lee94917b32022-03-18 17:52:09 -07002579}
2580
Ady Abrahamfcb16862022-10-10 14:35:21 -07002581TEST_F(FrameTimelineTest, jankClassification_presentFenceError) {
2582 auto erroneousPresentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2583 auto erroneousPresentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2584 auto validPresentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2585 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2586 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2587 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({72, 80, 80});
2588
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002589 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002590 mFrameTimeline->setSfPresent(26, erroneousPresentFence1);
2591
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002592 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002593 mFrameTimeline->setSfPresent(60, erroneousPresentFence2);
2594
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002595 mFrameTimeline->setSfWakeUp(sfToken3, 72, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002596 mFrameTimeline->setSfPresent(80, validPresentFence);
2597
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002598 erroneousPresentFence2->signalForTest(2);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002599 validPresentFence->signalForTest(80);
2600
2601 addEmptyDisplayFrame();
2602
2603 {
2604 auto displayFrame = getDisplayFrame(0);
2605 EXPECT_EQ(displayFrame->getActuals().presentTime, 26);
2606 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2607 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002608 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002609 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002610 }
2611 {
2612 auto displayFrame = getDisplayFrame(1);
2613 EXPECT_EQ(displayFrame->getActuals().presentTime, 60);
2614 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2615 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002616 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002617 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002618 }
2619 {
2620 auto displayFrame = getDisplayFrame(2);
2621 EXPECT_EQ(displayFrame->getActuals().presentTime, 80);
2622 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2623 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2624 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002625 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::None);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002626 }
2627}
2628
Alec Mouriadebf5c2021-01-05 12:57:36 -08002629TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
2630 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
2631}
2632
2633TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002634 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002635
2636 auto surfaceFrame1 =
2637 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002638 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002639 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002640 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2641 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2642 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2643 presentFence1->signalForTest(oneHundredMs);
2644 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2645
2646 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2647}
2648
2649TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002650 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2651 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002652 auto surfaceFrame1 =
2653 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002654 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002655 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002656 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2657 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2658 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2659 presentFence1->signalForTest(oneHundredMs);
2660 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2661
2662 auto surfaceFrame2 =
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 presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2667 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2668 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2669 presentFence2->signalForTest(twoHundredMs);
2670 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2671
2672 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
2673}
2674
2675TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002676 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2677 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002678 auto surfaceFrame1 =
2679 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002680 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002681 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002682 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2683 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2684 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2685 presentFence1->signalForTest(oneHundredMs);
2686 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2687
2688 auto surfaceFrame2 =
2689 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002690 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002691 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002692 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2693 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2694 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2695 presentFence2->signalForTest(twoHundredMs);
2696 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2697
2698 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
2699}
2700
2701TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002702 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2703 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002704 auto surfaceFrame1 =
2705 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002706 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002707 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002708 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2709 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2710 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2711 presentFence1->signalForTest(oneHundredMs);
2712 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2713
2714 auto surfaceFrame2 =
2715 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002716 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002717 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002718 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2719 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2720 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2721 presentFence2->signalForTest(twoHundredMs);
2722 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2723
2724 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2725}
2726
2727TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002728 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2729 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2730 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2731 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2732 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002733 auto surfaceFrame1 =
2734 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002735 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002736 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002737 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2738 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2739 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2740 presentFence1->signalForTest(oneHundredMs);
2741 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2742
2743 auto surfaceFrame2 =
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 presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2748 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2749 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2750 presentFence2->signalForTest(twoHundredMs);
2751 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2752
2753 auto surfaceFrame3 =
2754 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002755 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002756 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002757 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2758 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2759 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2760 presentFence3->signalForTest(threeHundredMs);
2761 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2762
2763 auto surfaceFrame4 =
2764 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002765 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002766 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002767 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2768 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2769 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2770 presentFence4->signalForTest(fiveHundredMs);
2771 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2772
2773 auto surfaceFrame5 =
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 presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2778 // Dropped frames will be excluded from fps computation
2779 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2780 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2781 presentFence5->signalForTest(sixHundredMs);
2782 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2783
2784 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2785}
2786
ramindaniea2bb822022-06-27 19:52:10 +00002787TEST_F(FrameTimelineTest, getMinTime) {
2788 // Use SurfaceFrame::getBaseTime to test the getMinTime.
2789 FrameTimelineInfo ftInfo;
2790
2791 // Valid prediction state test.
2792 ftInfo.vsyncId = 0L;
2793 mTokenManager->generateTokenForPredictions({10});
2794 auto surfaceFrame =
2795 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2796 sLayerNameOne, sLayerNameOne,
2797 /*isBuffer*/ true, sGameMode);
2798 ASSERT_EQ(surfaceFrame->getBaseTime(), 10);
2799
2800 // Test prediction state which is not valid.
2801 ftInfo.vsyncId = FrameTimelineInfo::INVALID_VSYNC_ID;
2802 surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2803 sLayerNameOne, sLayerNameOne,
2804 /*isBuffer*/ true, sGameMode);
2805 // Start time test.
2806 surfaceFrame->setActualStartTime(200);
2807 ASSERT_EQ(surfaceFrame->getBaseTime(), 200);
2808
2809 // End time test.
2810 surfaceFrame->setAcquireFenceTime(100);
2811 ASSERT_EQ(surfaceFrame->getBaseTime(), 100);
2812
2813 // Present time test.
2814 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2815 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2816 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2817 presentFence->signalForTest(std::chrono::nanoseconds(50ns).count());
2818 mFrameTimeline->setSfPresent(50, presentFence);
2819 ASSERT_EQ(surfaceFrame->getBaseTime(), 50);
2820}
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002821
2822TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingDisplayRate) {
2823 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2824 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2825 FrameTimelineInfo ftInfo;
2826 ftInfo.vsyncId = token1;
2827 ftInfo.inputEventId = sInputEventId;
2828 auto surfaceFrame =
2829 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2830 sLayerNameOne, sLayerNameOne,
2831 /*isBuffer*/ true, sGameMode);
2832
2833 mFrameTimeline->setSfWakeUp(token1, 20, RR_30, RR_11);
2834 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2835 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2836 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2837 mFrameTimeline->setSfPresent(50, presentFence1);
2838
2839 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 11);
2840}
2841
2842TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingAppFrameRate) {
2843 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2844 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2845 FrameTimelineInfo ftInfo;
2846 ftInfo.vsyncId = token1;
2847 ftInfo.inputEventId = sInputEventId;
2848 auto surfaceFrame =
2849 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2850 sLayerNameOne, sLayerNameOne,
2851 /*isBuffer*/ true, sGameMode);
2852 surfaceFrame->setRenderRate(RR_30);
2853 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
2854 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2855 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2856 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2857 mFrameTimeline->setSfPresent(50, presentFence1);
2858
2859 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 30);
2860}
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002861} // namespace android::frametimeline