blob: 0dfbd6185e68d61edee0c287ba7fdd3c7c99b7b0 [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;
Ady Abraham43a68c32024-09-04 19:21:20 -070087 constexpr bool kFilterFramesBeforeTraceStarts = false;
Alec Mouri9a29e672020-09-14 12:39:14 -070088 mTimeStats = std::make_shared<mock::TimeStats>();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000089 mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats, kSurfaceFlingerPid,
Ady Abraham43a68c32024-09-04 19:21:20 -070090 kTestThresholds, !kUseBootTimeClock,
91 kFilterFramesBeforeTraceStarts);
Adithya Srinivasan01189672020-10-20 14:23:05 -070092 mFrameTimeline->registerDataSource();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070093 mTokenManager = &mFrameTimeline->mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000094 mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
Adithya Srinivasan2d736322020-10-01 16:53:48 -070095 maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +000096 maxTokens = mTokenManager->kMaxTokens;
Pascal Mütschardd56514e2024-05-24 17:37:13 +020097
98 JankTracker::clearAndStartCollectingAllJankDataForTesting();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070099 }
100
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200101 void TearDown() override { JankTracker::clearAndStopCollectingAllJankDataForTesting(); }
102
Adithya Srinivasan01189672020-10-20 14:23:05 -0700103 // Each tracing session can be used for a single block of Start -> Stop.
104 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
105 perfetto::TraceConfig cfg;
106 cfg.set_duration_ms(500);
107 cfg.add_buffers()->set_size_kb(1024);
108 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
109 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
110
111 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
112 tracingSession->Setup(cfg);
113 return tracingSession;
114 }
115
116 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
117 perfetto::TracingSession* tracingSession) {
118 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
119 perfetto::protos::Trace trace;
120 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
121
122 std::vector<perfetto::protos::TracePacket> packets;
123 for (const auto& packet : trace.packet()) {
124 if (!packet.has_frame_timeline_event()) {
125 continue;
126 }
127 packets.emplace_back(packet);
128 }
129 return packets;
130 }
131
Ady Abraham57a8ab42023-01-26 15:28:19 -0800132 void addEmptySurfaceFrame() {
133 auto surfaceFrame =
134 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
135 sLayerNameOne, sLayerNameOne,
136 /*isBuffer*/ false, sGameMode);
137 mFrameTimeline->addSurfaceFrame(std::move(surfaceFrame));
138 }
139
Adithya Srinivasan01189672020-10-20 14:23:05 -0700140 void addEmptyDisplayFrame() {
141 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000142 // Trigger a flushPresentFence by calling setSfPresent for the next frame
Adithya Srinivasan01189672020-10-20 14:23:05 -0700143 mFrameTimeline->setSfPresent(2500, presentFence1);
144 }
145
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000146 void flushTokens() {
147 for (size_t i = 0; i < maxTokens; i++) {
148 mTokenManager->generateTokenForPredictions({});
149 }
150 EXPECT_EQ(getPredictions().size(), maxTokens);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700151 }
152
153 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
154 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800155 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
156 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700157 }
158
159 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
160 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
161 return mFrameTimeline->mDisplayFrames[idx];
162 }
163
164 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
165 return a.startTime == b.startTime && a.endTime == b.endTime &&
166 a.presentTime == b.presentTime;
167 }
168
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000169 const std::map<int64_t, TimelineItem>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700170 return mTokenManager->mPredictions;
171 }
172
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000173 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700174 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
175 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
176 }
177
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000178 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
179
180 void flushTrace() {
181 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
182 FrameTimelineDataSource::Trace(
183 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
184 }
185
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200186 std::vector<gui::JankData> getLayerOneJankData() {
187 BackgroundExecutor::getLowPriorityInstance().flushQueue();
188 return JankTracker::getCollectedJankDataForTesting(sLayerIdOne);
189 }
190
191 std::vector<gui::JankData> getLayerTwoJankData() {
192 BackgroundExecutor::getLowPriorityInstance().flushQueue();
193 return JankTracker::getCollectedJankDataForTesting(sLayerIdTwo);
194 }
195
Alec Mouri9a29e672020-09-14 12:39:14 -0700196 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700197 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
198 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000199 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700200 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700201 uint32_t* maxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000202 size_t maxTokens;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000203 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasanead17162021-02-18 02:17:37 +0000204 static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan54996e22021-06-25 22:26:45 +0000205 static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(0ns).count();
Adithya Srinivasanead17162021-02-18 02:17:37 +0000206 static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800207 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
208 kDeadlineThreshold,
209 kStartThreshold};
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700210};
211
212TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
213 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000214 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000215 flushTokens();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700216 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
217 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
218
219 // token1 should have expired
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700220 EXPECT_EQ(predictions.has_value(), false);
221
222 predictions = mTokenManager->getPredictionsForToken(token2);
223 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
224}
225
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700226TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800227 auto surfaceFrame1 =
228 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000229 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000230 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -0800231 auto surfaceFrame2 =
232 mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000233 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000234 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700235 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
236 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
237}
238
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700239TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800240 auto surfaceFrame =
241 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000242 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000243 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700244 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
245}
246
247TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
248 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000249 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -0800250 FrameTimelineInfo ftInfo;
251 ftInfo.vsyncId = token1;
252 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000253 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800254 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
255 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000256 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700257
258 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
259}
260
261TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
262 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800263 FrameTimelineInfo ftInfo;
264 ftInfo.vsyncId = token1;
265 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000266 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800267 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
268 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000269 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700270
271 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
272 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
273}
274
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000275TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
276 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
277 constexpr int32_t inputEventId = 1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800278 FrameTimelineInfo ftInfo;
279 ftInfo.vsyncId = token1;
280 ftInfo.inputEventId = inputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000281 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800282 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
283 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000284 /*isBuffer*/ true, sGameMode);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000285
286 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
287}
288
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700289TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
290 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700291 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800292 FrameTimelineInfo ftInfo;
293 ftInfo.vsyncId = token1;
294 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000295 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800296 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
297 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000298 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700299
300 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200301 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000302 surfaceFrame1->setDropTime(12);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800303 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
304 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700305 mFrameTimeline->setSfPresent(25, presentFence1);
306 presentFence1->signalForTest(30);
307
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000308 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700309
310 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
311 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000312 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
313 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700314 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
315}
316
317TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800318 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800319 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700320 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
321 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700322 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800323 FrameTimelineInfo ftInfo;
324 ftInfo.vsyncId = surfaceFrameToken1;
325 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700326 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800327 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
328 sLayerNameOne, sLayerNameOne,
329 /*isBuffer*/ true, sGameMode);
Alec Mouri9a29e672020-09-14 12:39:14 -0700330 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800331 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdTwo,
332 sLayerNameTwo, sLayerNameTwo,
333 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200334 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800335 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
336 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
337 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
338 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700339 mFrameTimeline->setSfPresent(26, presentFence1);
340 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800341 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
342 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700343 presentFence1->signalForTest(42);
344
345 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800346 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700347 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
348 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
349
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000350 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700351
352 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800353 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700354 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
355 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100356 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
Ying Wei96eb5352023-11-21 17:37:21 +0000357 EXPECT_NE(surfaceFrame1->getJankSeverityType(), std::nullopt);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100358 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Ying Wei96eb5352023-11-21 17:37:21 +0000359 EXPECT_NE(surfaceFrame2->getJankSeverityType(), std::nullopt);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200360
361 EXPECT_EQ(getLayerOneJankData().size(), 1u);
362 EXPECT_EQ(getLayerTwoJankData().size(), 1u);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700363}
364
Ady Abraham14beed72024-05-15 17:16:45 -0700365TEST_F(FrameTimelineTest, displayFrameSkippedComposition) {
366 // Layer specific increment
367 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(1);
368 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
369 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
370 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
371 FrameTimelineInfo ftInfo;
372 ftInfo.vsyncId = surfaceFrameToken1;
373 ftInfo.inputEventId = sInputEventId;
374 auto surfaceFrame1 =
375 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
376 sLayerNameOne, sLayerNameOne,
377 /*isBuffer*/ true, sGameMode);
378 auto surfaceFrame2 =
379 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdTwo,
380 sLayerNameTwo, sLayerNameTwo,
381 /*isBuffer*/ true, sGameMode);
382
383 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
384 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
385 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
386 mFrameTimeline->onCommitNotComposited();
387
388 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 30);
389 ASSERT_NE(surfaceFrame1->getJankType(), std::nullopt);
390 EXPECT_EQ(*surfaceFrame1->getJankType(), JankType::None);
391 ASSERT_NE(surfaceFrame1->getJankSeverityType(), std::nullopt);
392 EXPECT_EQ(*surfaceFrame1->getJankSeverityType(), JankSeverityType::None);
393
394 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
395 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
396 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
397 mFrameTimeline->setSfPresent(26, presentFence1);
398
399 auto displayFrame = getDisplayFrame(0);
400 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 0);
401 presentFence1->signalForTest(42);
402
403 // Fences haven't been flushed yet, so it should be 0
404 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
405 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
406
407 addEmptyDisplayFrame();
408
409 // Fences have flushed, so the present timestamps should be updated
410 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
411 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
412 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
413 EXPECT_NE(surfaceFrame2->getJankSeverityType(), std::nullopt);
414}
415
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700416TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
417 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
418 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800419 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800420 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800421 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700422 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700423 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
424 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
425 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
426 int64_t sfToken = mTokenManager->generateTokenForPredictions(
427 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800428 FrameTimelineInfo ftInfo;
429 ftInfo.vsyncId = surfaceFrameToken;
430 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700431 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800432 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000433 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000434 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200435 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800436 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
437 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700438 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
439 presentFence->signalForTest(32 + frameTimeFactor);
440 frameTimeFactor += 30;
441 }
442 auto displayFrame0 = getDisplayFrame(0);
443
444 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800445 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700446
447 // Add one more display frame
448 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
449 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
450 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
451 int64_t sfToken = mTokenManager->generateTokenForPredictions(
452 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800453 FrameTimelineInfo ftInfo;
454 ftInfo.vsyncId = surfaceFrameToken;
455 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700456 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800457 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
458 sLayerNameOne, sLayerNameOne,
459 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200460 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800461 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
462 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700463 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
464 presentFence->signalForTest(32 + frameTimeFactor);
465 displayFrame0 = getDisplayFrame(0);
466
467 // The window should have slided by 1 now and the previous 0th display frame
468 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800469 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200470
471 EXPECT_EQ(getLayerOneJankData().size(), *maxDisplayFrames);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700472}
473
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700474TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000475 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
476 "acquireFenceAfterQueue",
477 "acquireFenceAfterQueue",
478 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700479 surfaceFrame->setActualQueueTime(123);
480 surfaceFrame->setAcquireFenceTime(456);
481 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
482}
483
Vishnu Nairbd7d07e2024-07-08 13:37:11 -0700484TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceUnsignaled) {
485 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
486 "acquireFenceAfterQueue",
487 "acquireFenceAfterQueue",
488 /*isBuffer*/ true, sGameMode);
489 surfaceFrame->setActualQueueTime(123);
490 surfaceFrame->setAcquireFenceTime(Fence::SIGNAL_TIME_PENDING);
491 EXPECT_EQ(surfaceFrame->getActuals().endTime, 123);
492}
493
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700494TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000495 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
496 "acquireFenceAfterQueue",
497 "acquireFenceAfterQueue",
498 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700499 surfaceFrame->setActualQueueTime(456);
500 surfaceFrame->setAcquireFenceTime(123);
501 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
502}
503
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700504TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
505 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
506 presentFence->signalForTest(2);
507
508 // Size shouldn't exceed maxDisplayFrames - 64
509 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700510 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800511 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000512 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000513 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700514 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200515 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800516 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
517 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700518 mFrameTimeline->setSfPresent(27, presentFence);
519 }
520 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
521
522 // Increase the size to 256
523 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000524 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700525
526 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700527 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800528 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000529 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000530 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700531 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200532 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800533 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
534 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700535 mFrameTimeline->setSfPresent(27, presentFence);
536 }
537 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
538
539 // Shrink the size to 128
540 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000541 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700542
543 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700544 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800545 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000546 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000547 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700548 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200549 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800550 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
551 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700552 mFrameTimeline->setSfPresent(27, presentFence);
553 }
554 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
555}
Alec Mouri9a29e672020-09-14 12:39:14 -0700556
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000557TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200558 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000559
560 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
561 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
562 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800563 FrameTimelineInfo ftInfo;
564 ftInfo.vsyncId = surfaceFrameToken1;
565 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000566
567 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800568 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
569 sLayerNameOne, sLayerNameOne,
570 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200571 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000572 surfaceFrame1->setAcquireFenceTime(20);
573 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
574 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
575
576 mFrameTimeline->setSfPresent(59, presentFence1);
577 presentFence1->signalForTest(-1);
578 addEmptyDisplayFrame();
579
580 auto displayFrame0 = getDisplayFrame(0);
Ady Abrahamfcb16862022-10-10 14:35:21 -0700581 EXPECT_EQ(displayFrame0->getActuals().presentTime, 59);
Ady Abrahamb1e10d12023-03-13 15:23:54 -0700582 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +0000583 EXPECT_EQ(displayFrame0->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000584 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
585 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +0000586 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000587}
588
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800589// Tests related to TimeStats
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000590TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200591 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000592 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
593 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
594 int64_t surfaceFrameToken1 = -1;
595 int64_t sfToken1 = -1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800596 FrameTimelineInfo ftInfo;
597 ftInfo.vsyncId = surfaceFrameToken1;
598 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000599
600 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800601 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
602 sLayerNameOne, sLayerNameOne,
603 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200604 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000605 surfaceFrame1->setAcquireFenceTime(20);
606 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
607 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
608 presentFence1->signalForTest(70);
609
610 mFrameTimeline->setSfPresent(59, presentFence1);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200611
612 EXPECT_EQ(getLayerOneJankData().size(), 0u);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000613}
614
Alec Mouri9a29e672020-09-14 12:39:14 -0700615TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200616 Fps refreshRate = RR_11;
Alec Mouri9a29e672020-09-14 12:39:14 -0700617 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800618 incrementJankyFrames(
619 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000620 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000621 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800622 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700623 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000624 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
625 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800626 FrameTimelineInfo ftInfo;
627 ftInfo.vsyncId = surfaceFrameToken1;
628 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000629
Alec Mouri9a29e672020-09-14 12:39:14 -0700630 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800631 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
632 sLayerNameOne, sLayerNameOne,
633 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200634 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000635 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800636 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
637 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000638 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700639
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000640 mFrameTimeline->setSfPresent(62, presentFence1);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200641
642 auto jankData = getLayerOneJankData();
643 EXPECT_EQ(jankData.size(), 1u);
644 EXPECT_EQ(jankData[0].jankType, JankType::SurfaceFlingerCpuDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700645}
646
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000647TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfGpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200648 Fps refreshRate = RR_11;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000649 EXPECT_CALL(*mTimeStats,
650 incrementJankyFrames(
651 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000652 sLayerNameOne, sGameMode,
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000653 JankType::SurfaceFlingerGpuDeadlineMissed, 4, 10,
654 0}));
655 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
656 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
657 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
658 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800659 FrameTimelineInfo ftInfo;
660 ftInfo.vsyncId = surfaceFrameToken1;
661 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000662
663 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800664 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
665 sLayerNameOne, sLayerNameOne,
666 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200667 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000668 surfaceFrame1->setAcquireFenceTime(20);
669 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
670 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
671 gpuFence1->signalForTest(64);
672 presentFence1->signalForTest(70);
673
674 mFrameTimeline->setSfPresent(59, presentFence1, gpuFence1);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200675
676 auto jankData = getLayerOneJankData();
677 EXPECT_EQ(jankData.size(), 1u);
678 EXPECT_EQ(jankData[0].jankType, JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000679}
680
Alec Mouri9a29e672020-09-14 12:39:14 -0700681TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200682 Fps refreshRate = RR_30;
Alec Mouri9a29e672020-09-14 12:39:14 -0700683 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800684 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000685 sLayerNameOne, sGameMode,
686 JankType::DisplayHAL, -4, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800687
Alec Mouri9a29e672020-09-14 12:39:14 -0700688 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000689 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
690 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800691 FrameTimelineInfo ftInfo;
692 ftInfo.vsyncId = surfaceFrameToken1;
693 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000694
Alec Mouri9a29e672020-09-14 12:39:14 -0700695 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800696 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
697 sLayerNameOne, sLayerNameOne,
698 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200699 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800700 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000701 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800702 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000703 presentFence1->signalForTest(90);
704 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800705 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +0000706 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200707
708 auto jankData = getLayerOneJankData();
709 EXPECT_EQ(jankData.size(), 1u);
710 EXPECT_EQ(jankData[0].jankType, JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700711}
712
713TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700714 Fps refreshRate = 11_Hz;
Alec Mouri9a29e672020-09-14 12:39:14 -0700715 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000716 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000717 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000718 JankType::AppDeadlineMissed, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000719 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700720 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000721 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
722 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800723 FrameTimelineInfo ftInfo;
724 ftInfo.vsyncId = surfaceFrameToken1;
725 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000726
Alec Mouri9a29e672020-09-14 12:39:14 -0700727 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800728 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
729 sLayerNameOne, sLayerNameOne,
730 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000731 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200732 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700733
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800734 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
735 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000736 presentFence1->signalForTest(90);
737 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100738
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800739 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000740 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Partial);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200741
742 auto jankData = getLayerOneJankData();
743 EXPECT_EQ(jankData.size(), 1u);
744 EXPECT_EQ(jankData[0].jankType, JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700745}
746
Adithya Srinivasanead17162021-02-18 02:17:37 +0000747TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000748 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000749 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000750 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000751 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000752 JankType::SurfaceFlingerScheduling,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000753 -4, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000754 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000755 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
756 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800757 FrameTimelineInfo ftInfo;
758 ftInfo.vsyncId = surfaceFrameToken1;
759 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000760
Adithya Srinivasanead17162021-02-18 02:17:37 +0000761 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800762 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
763 sLayerNameOne, sLayerNameOne,
764 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000765 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200766 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000767
768 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
769 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000770 presentFence1->signalForTest(60);
771 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000772
773 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +0000774 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200775
776 auto jankData = getLayerOneJankData();
777 EXPECT_EQ(jankData.size(), 1u);
778 EXPECT_EQ(jankData[0].jankType, JankType::SurfaceFlingerScheduling);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000779}
780
781TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000782 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000783 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000784 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000785 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000786 JankType::PredictionError, -4, 5,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000787 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000788 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000789 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
790 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800791 FrameTimelineInfo ftInfo;
792 ftInfo.vsyncId = surfaceFrameToken1;
793 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000794
Adithya Srinivasanead17162021-02-18 02:17:37 +0000795 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800796 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
797 sLayerNameOne, sLayerNameOne,
798 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000799 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200800 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000801
802 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
803 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000804 presentFence1->signalForTest(65);
805 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000806
807 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +0000808 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Partial);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200809
810 auto jankData = getLayerOneJankData();
811 EXPECT_EQ(jankData.size(), 1u);
812 EXPECT_EQ(jankData[0].jankType, JankType::PredictionError);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000813}
814
815TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000816 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000817 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000818 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000819 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000820 JankType::BufferStuffing, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000821 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000822 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000823 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
824 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800825 FrameTimelineInfo ftInfo;
826 ftInfo.vsyncId = surfaceFrameToken1;
827 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000828
Adithya Srinivasanead17162021-02-18 02:17:37 +0000829 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800830 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
831 sLayerNameOne, sLayerNameOne,
832 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000833 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200834 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000835
836 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000837 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000838 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000839 presentFence1->signalForTest(90);
840 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000841
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000842 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +0000843 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200844
845 auto jankData = getLayerOneJankData();
846 EXPECT_EQ(jankData.size(), 1u);
847 EXPECT_EQ(jankData[0].jankType, JankType::BufferStuffing);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000848}
849
Alec Mouri363faf02021-01-29 16:34:55 -0800850TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200851 Fps refreshRate = RR_11;
852 Fps renderRate = RR_30;
Alec Mouri363faf02021-01-29 16:34:55 -0800853 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000854 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne,
855 sLayerNameOne, sGameMode,
856 JankType::AppDeadlineMissed, -4, 0,
857 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800858 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000859 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
860 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800861 FrameTimelineInfo ftInfo;
862 ftInfo.vsyncId = surfaceFrameToken1;
863 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000864
Alec Mouri363faf02021-01-29 16:34:55 -0800865 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800866 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
867 sLayerNameOne, sLayerNameOne,
868 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000869 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200870 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800871
872 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
873 surfaceFrame1->setRenderRate(renderRate);
874 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000875 presentFence1->signalForTest(90);
876 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800877
878 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000879 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200880
881 auto jankData = getLayerOneJankData();
882 EXPECT_EQ(jankData.size(), 1u);
883 EXPECT_EQ(jankData[0].jankType, JankType::AppDeadlineMissed);
Alec Mouri363faf02021-01-29 16:34:55 -0800884}
885
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000886TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200887 Fps refreshRate = RR_11;
888 Fps renderRate = RR_30;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000889
890 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000891 incrementJankyFrames(
892 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000893 sGameMode,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000894 JankType::Unknown | JankType::AppDeadlineMissed,
Adithya Srinivasande272452021-04-10 00:21:00 +0000895 0, 0, 25}));
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000896 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
897 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
898 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800899 FrameTimelineInfo ftInfo;
900 ftInfo.vsyncId = surfaceFrameToken1;
901 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000902
903 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800904 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
905 sLayerNameOne, sLayerNameOne,
906 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000907 surfaceFrame1->setAcquireFenceTime(45);
908 // Trigger a prediction expiry
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000909 flushTokens();
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200910 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000911
912 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
913 surfaceFrame1->setRenderRate(renderRate);
914 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
915 presentFence1->signalForTest(90);
916 mFrameTimeline->setSfPresent(86, presentFence1);
917
918 auto displayFrame = getDisplayFrame(0);
919 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +0000920 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000921 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
922 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
923 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
924
925 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000926 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000927 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200928
929 auto jankData = getLayerOneJankData();
930 EXPECT_EQ(jankData.size(), 1u);
931 EXPECT_EQ(jankData[0].jankType, JankType::Unknown | JankType::AppDeadlineMissed);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000932}
933
Adithya Srinivasan01189672020-10-20 14:23:05 -0700934/*
935 * Tracing Tests
936 *
937 * Trace packets are flushed all the way only when the next packet is traced.
938 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
939 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
940 * will have additional empty frames created for this reason.
941 */
942TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
943 auto tracingSession = getTracingSessionForTest();
944 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700945 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800946 FrameTimelineInfo ftInfo;
947 ftInfo.vsyncId = token1;
948 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000949 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800950 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
951 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000952 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700953
954 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200955 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800956 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
957 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700958 mFrameTimeline->setSfPresent(25, presentFence1);
959 presentFence1->signalForTest(30);
960
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000961 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700962
963 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000964 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700965}
966
967TEST_F(FrameTimelineTest, tracing_sanityTest) {
968 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800969 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800970 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700971 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700972
973 tracingSession->StartBlocking();
974 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
975 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800976 FrameTimelineInfo ftInfo;
977 ftInfo.vsyncId = token1;
978 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000979 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800980 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
981 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000982 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700983
984 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200985 mFrameTimeline->setSfWakeUp(token2, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800986 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
987 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700988 mFrameTimeline->setSfPresent(25, presentFence1);
989 presentFence1->signalForTest(30);
990
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000991 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000992 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700993 tracingSession->StopBlocking();
994
995 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000996 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000997 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700998}
999
1000TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
1001 auto tracingSession = getTracingSessionForTest();
1002 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001003
1004 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001005
1006 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001007 mFrameTimeline->setSfWakeUp(-1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001008 mFrameTimeline->setSfPresent(25, presentFence1);
1009 presentFence1->signalForTest(30);
1010
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001011 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001012 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001013 tracingSession->StopBlocking();
1014
1015 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001016 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001017}
1018
1019TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
1020 auto tracingSession = getTracingSessionForTest();
1021 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001022
1023 tracingSession->StartBlocking();
1024 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -08001025 auto surfaceFrame1 =
1026 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001027 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001028 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001029
1030 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001031 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001032 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1033 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001034 mFrameTimeline->setSfPresent(25, presentFence1);
1035 presentFence1->signalForTest(30);
1036
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001037 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001038 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001039 tracingSession->StopBlocking();
1040
1041 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001042 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
1043 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001044 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001045}
1046
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001047ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
1048 pid_t pid) {
1049 ProtoExpectedDisplayFrameStart proto;
1050 proto.set_cookie(cookie);
1051 proto.set_token(token);
1052 proto.set_pid(pid);
1053 return proto;
1054}
1055
1056ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
1057 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Ying Wei96eb5352023-11-21 17:37:21 +00001058 bool gpuComposition, ProtoJankType jankType, ProtoJankSeverityType jankSeverityType,
1059 ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001060 ProtoActualDisplayFrameStart proto;
1061 proto.set_cookie(cookie);
1062 proto.set_token(token);
1063 proto.set_pid(pid);
1064 proto.set_present_type(presentType);
1065 proto.set_on_time_finish(onTimeFinish);
1066 proto.set_gpu_composition(gpuComposition);
1067 proto.set_jank_type(jankType);
Ying Wei96eb5352023-11-21 17:37:21 +00001068 proto.set_jank_severity_type(jankSeverityType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001069 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001070 return proto;
1071}
1072
1073ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
1074 int64_t displayFrameToken,
1075 pid_t pid,
1076 std::string layerName) {
1077 ProtoExpectedSurfaceFrameStart proto;
1078 proto.set_cookie(cookie);
1079 proto.set_token(token);
1080 proto.set_display_frame_token(displayFrameToken);
1081 proto.set_pid(pid);
1082 proto.set_layer_name(layerName);
1083 return proto;
1084}
1085
1086ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
1087 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
1088 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Ying Wei96eb5352023-11-21 17:37:21 +00001089 ProtoJankType jankType, ProtoJankSeverityType jankSeverityType,
1090 ProtoPredictionType predictionType, bool isBuffer) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001091 ProtoActualSurfaceFrameStart proto;
1092 proto.set_cookie(cookie);
1093 proto.set_token(token);
1094 proto.set_display_frame_token(displayFrameToken);
1095 proto.set_pid(pid);
1096 proto.set_layer_name(layerName);
1097 proto.set_present_type(presentType);
1098 proto.set_on_time_finish(onTimeFinish);
1099 proto.set_gpu_composition(gpuComposition);
1100 proto.set_jank_type(jankType);
Ying Wei96eb5352023-11-21 17:37:21 +00001101 proto.set_jank_severity_type(jankSeverityType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001102 proto.set_prediction_type(predictionType);
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001103 proto.set_is_buffer(isBuffer);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001104 return proto;
1105}
1106
1107ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
1108 ProtoFrameEnd proto;
1109 proto.set_cookie(cookie);
1110 return proto;
1111}
1112
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001113void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
1114 const ProtoExpectedDisplayFrameStart& source) {
1115 ASSERT_TRUE(received.has_cookie());
1116 EXPECT_EQ(received.cookie(), source.cookie());
1117
Adithya Srinivasan01189672020-10-20 14:23:05 -07001118 ASSERT_TRUE(received.has_token());
1119 EXPECT_EQ(received.token(), source.token());
1120
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001121 ASSERT_TRUE(received.has_pid());
1122 EXPECT_EQ(received.pid(), source.pid());
1123}
1124
1125void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
1126 const ProtoActualDisplayFrameStart& source) {
1127 ASSERT_TRUE(received.has_cookie());
1128 EXPECT_EQ(received.cookie(), source.cookie());
1129
1130 ASSERT_TRUE(received.has_token());
1131 EXPECT_EQ(received.token(), source.token());
1132
1133 ASSERT_TRUE(received.has_pid());
1134 EXPECT_EQ(received.pid(), source.pid());
1135
Adithya Srinivasan01189672020-10-20 14:23:05 -07001136 ASSERT_TRUE(received.has_present_type());
1137 EXPECT_EQ(received.present_type(), source.present_type());
1138 ASSERT_TRUE(received.has_on_time_finish());
1139 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1140 ASSERT_TRUE(received.has_gpu_composition());
1141 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1142 ASSERT_TRUE(received.has_jank_type());
1143 EXPECT_EQ(received.jank_type(), source.jank_type());
Ying Wei96eb5352023-11-21 17:37:21 +00001144 ASSERT_TRUE(received.has_jank_severity_type());
1145 EXPECT_EQ(received.jank_severity_type(), source.jank_severity_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001146 ASSERT_TRUE(received.has_prediction_type());
1147 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001148}
1149
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001150void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
1151 const ProtoExpectedSurfaceFrameStart& source) {
1152 ASSERT_TRUE(received.has_cookie());
1153 EXPECT_EQ(received.cookie(), source.cookie());
1154
Adithya Srinivasan01189672020-10-20 14:23:05 -07001155 ASSERT_TRUE(received.has_token());
1156 EXPECT_EQ(received.token(), source.token());
1157
1158 ASSERT_TRUE(received.has_display_frame_token());
1159 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1160
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001161 ASSERT_TRUE(received.has_pid());
1162 EXPECT_EQ(received.pid(), source.pid());
1163
1164 ASSERT_TRUE(received.has_layer_name());
1165 EXPECT_EQ(received.layer_name(), source.layer_name());
1166}
1167
1168void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
1169 const ProtoActualSurfaceFrameStart& source) {
1170 ASSERT_TRUE(received.has_cookie());
1171 EXPECT_EQ(received.cookie(), source.cookie());
1172
1173 ASSERT_TRUE(received.has_token());
1174 EXPECT_EQ(received.token(), source.token());
1175
1176 ASSERT_TRUE(received.has_display_frame_token());
1177 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1178
1179 ASSERT_TRUE(received.has_pid());
1180 EXPECT_EQ(received.pid(), source.pid());
1181
1182 ASSERT_TRUE(received.has_layer_name());
1183 EXPECT_EQ(received.layer_name(), source.layer_name());
1184
Adithya Srinivasan01189672020-10-20 14:23:05 -07001185 ASSERT_TRUE(received.has_present_type());
1186 EXPECT_EQ(received.present_type(), source.present_type());
1187 ASSERT_TRUE(received.has_on_time_finish());
1188 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1189 ASSERT_TRUE(received.has_gpu_composition());
1190 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1191 ASSERT_TRUE(received.has_jank_type());
1192 EXPECT_EQ(received.jank_type(), source.jank_type());
Ying Wei96eb5352023-11-21 17:37:21 +00001193 ASSERT_TRUE(received.has_jank_severity_type());
1194 EXPECT_EQ(received.jank_severity_type(), source.jank_severity_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001195 ASSERT_TRUE(received.has_prediction_type());
1196 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001197 ASSERT_TRUE(received.has_is_buffer());
1198 EXPECT_EQ(received.is_buffer(), source.is_buffer());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001199}
Adithya Srinivasan01189672020-10-20 14:23:05 -07001200
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001201void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
1202 ASSERT_TRUE(received.has_cookie());
1203 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001204}
1205
Sally Qi2269a692024-05-17 18:02:28 -07001206TEST_F(FrameTimelineTest, traceDisplayFrameNoSkipped) {
1207 // setup 2 display frames
1208 // DF 1: [22, 30] -> [0, 11]
1209 // DF 2: [82, 90] -> SF [5, 16]
1210 auto tracingSession = getTracingSessionForTest();
1211 tracingSession->StartBlocking();
1212 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1213 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 100});
1214 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({0, 11, 25});
1215 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1216 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1217
1218 int64_t traceCookie = snoopCurrentTraceCookie();
1219
1220 // set up 1st display frame
1221 FrameTimelineInfo ftInfo1;
1222 ftInfo1.vsyncId = surfaceFrameToken1;
1223 ftInfo1.inputEventId = sInputEventId;
1224 auto surfaceFrame1 =
1225 mFrameTimeline->createSurfaceFrameForToken(ftInfo1, sPidOne, sUidOne, sLayerIdOne,
1226 sLayerNameOne, sLayerNameOne,
1227 /*isBuffer*/ true, sGameMode);
1228 surfaceFrame1->setAcquireFenceTime(11);
1229 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_30);
1230 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1231 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1232 mFrameTimeline->setSfPresent(30, presentFence1);
1233 presentFence1->signalForTest(40);
1234
1235 // Trigger a flush by finalizing the next DisplayFrame
1236 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1237 FrameTimelineInfo ftInfo2;
1238 ftInfo2.vsyncId = surfaceFrameToken2;
1239 ftInfo2.inputEventId = sInputEventId;
1240 auto surfaceFrame2 =
1241 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1242 sLayerNameOne, sLayerNameOne,
1243 /*isBuffer*/ true, sGameMode);
1244
1245 // set up 2nd display frame
1246 surfaceFrame2->setAcquireFenceTime(16);
1247 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_11, RR_30);
1248 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1249 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1250 mFrameTimeline->setSfPresent(90, presentFence2);
1251 presentFence2->signalForTest(100);
1252
1253 // the token of skipped Display Frame
1254 auto protoSkippedActualDisplayFrameStart =
1255 createProtoActualDisplayFrameStart(traceCookie + 9, 0, kSurfaceFlingerPid,
1256 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1257 FrameTimelineEvent::JANK_DROPPED,
1258 FrameTimelineEvent::SEVERITY_NONE,
1259 FrameTimelineEvent::PREDICTION_VALID);
1260 auto protoSkippedActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 9);
1261
1262 // Trigger a flush by finalizing the next DisplayFrame
1263 addEmptyDisplayFrame();
1264 flushTrace();
1265 tracingSession->StopBlocking();
1266
1267 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1268 // 8 Valid Display Frames + 8 Valid Surface Frames + no Skipped Display Frames
1269 EXPECT_EQ(packets.size(), 16u);
1270}
1271
Sally Qiaa107742023-09-29 14:53:14 -07001272TEST_F(FrameTimelineTest, traceDisplayFrameSkipped) {
Sally Qif5721252023-11-17 11:14:53 -08001273 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::add_sf_skipped_frames_to_trace,
1274 true);
1275
Sally Qiaa107742023-09-29 14:53:14 -07001276 // setup 2 display frames
1277 // DF 1: [22,40] -> [5, 40]
1278 // DF : [36, 70] (Skipped one, added by the trace)
1279 // DF 2: [82, 100] -> SF [25, 70]
1280 auto tracingSession = getTracingSessionForTest();
1281 tracingSession->StartBlocking();
1282 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1283 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 100});
1284 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1285 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1286 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1287
1288 int64_t traceCookie = snoopCurrentTraceCookie();
1289
1290 // set up 1st display frame
1291 FrameTimelineInfo ftInfo1;
1292 ftInfo1.vsyncId = surfaceFrameToken1;
1293 ftInfo1.inputEventId = sInputEventId;
1294 auto surfaceFrame1 =
1295 mFrameTimeline->createSurfaceFrameForToken(ftInfo1, sPidOne, sUidOne, sLayerIdOne,
1296 sLayerNameOne, sLayerNameOne,
1297 /*isBuffer*/ true, sGameMode);
1298 surfaceFrame1->setAcquireFenceTime(16);
1299 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_30);
1300 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1301 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1302 mFrameTimeline->setSfPresent(30, presentFence1);
1303 presentFence1->signalForTest(40);
1304
1305 // Trigger a flush by finalizing the next DisplayFrame
1306 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1307 FrameTimelineInfo ftInfo2;
1308 ftInfo2.vsyncId = surfaceFrameToken2;
1309 ftInfo2.inputEventId = sInputEventId;
1310 auto surfaceFrame2 =
1311 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1312 sLayerNameOne, sLayerNameOne,
1313 /*isBuffer*/ true, sGameMode);
1314
1315 // set up 2nd display frame
1316 surfaceFrame2->setAcquireFenceTime(36);
1317 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_11, RR_30);
1318 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1319 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1320 mFrameTimeline->setSfPresent(90, presentFence2);
1321 presentFence2->signalForTest(100);
1322
1323 // the token of skipped Display Frame
1324 auto protoSkippedActualDisplayFrameStart =
1325 createProtoActualDisplayFrameStart(traceCookie + 9, 0, kSurfaceFlingerPid,
1326 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1327 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001328 FrameTimelineEvent::SEVERITY_NONE,
Sally Qiaa107742023-09-29 14:53:14 -07001329 FrameTimelineEvent::PREDICTION_VALID);
1330 auto protoSkippedActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 9);
1331
1332 // Trigger a flush by finalizing the next DisplayFrame
1333 addEmptyDisplayFrame();
1334 flushTrace();
1335 tracingSession->StopBlocking();
1336
1337 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1338 // 8 Valid Display Frames + 8 Valid Surface Frames + 2 Skipped Display Frames
1339 EXPECT_EQ(packets.size(), 18u);
1340
1341 // Packet - 16: Actual skipped Display Frame Start
1342 // the timestamp should be equal to the 2nd expected surface frame's end time
1343 const auto& packet16 = packets[16];
1344 ASSERT_TRUE(packet16.has_timestamp());
1345 EXPECT_EQ(packet16.timestamp(), 36u);
1346 ASSERT_TRUE(packet16.has_frame_timeline_event());
1347
1348 const auto& event16 = packet16.frame_timeline_event();
1349 const auto& actualSkippedDisplayFrameStart = event16.actual_display_frame_start();
1350 validateTraceEvent(actualSkippedDisplayFrameStart, protoSkippedActualDisplayFrameStart);
1351
1352 // Packet - 17: Actual skipped Display Frame End
1353 // the timestamp should be equal to the 2nd expected surface frame's present time
1354 const auto& packet17 = packets[17];
1355 ASSERT_TRUE(packet17.has_timestamp());
1356 EXPECT_EQ(packet17.timestamp(), 70u);
1357 ASSERT_TRUE(packet17.has_frame_timeline_event());
1358
1359 const auto& event17 = packet17.frame_timeline_event();
1360 const auto& actualSkippedDisplayFrameEnd = event17.frame_end();
1361 validateTraceEvent(actualSkippedDisplayFrameEnd, protoSkippedActualDisplayFrameEnd);
1362}
1363
Adithya Srinivasan01189672020-10-20 14:23:05 -07001364TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
1365 auto tracingSession = getTracingSessionForTest();
1366 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001367
1368 tracingSession->StartBlocking();
Ady Abraham57a8ab42023-01-26 15:28:19 -08001369
1370 // Add an empty surface frame so that display frame would get traced.
1371 addEmptySurfaceFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001372 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001373
1374 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001375 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001376 mFrameTimeline->setSfPresent(26, presentFence1);
1377 presentFence1->signalForTest(31);
1378
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001379 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001380 auto protoExpectedDisplayFrameStart =
1381 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1382 kSurfaceFlingerPid);
1383 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1384 auto protoActualDisplayFrameStart =
1385 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
1386 kSurfaceFlingerPid,
1387 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001388 FrameTimelineEvent::JANK_NONE,
Ying Wei96eb5352023-11-21 17:37:21 +00001389 FrameTimelineEvent::SEVERITY_NONE,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001390 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001391 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001392
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001393 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001394 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001395 tracingSession->StopBlocking();
1396
1397 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001398 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001399
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001400 // Packet - 0 : ExpectedDisplayFrameStart
1401 const auto& packet0 = packets[0];
1402 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001403 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001404 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001405
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001406 const auto& event0 = packet0.frame_timeline_event();
1407 ASSERT_TRUE(event0.has_expected_display_frame_start());
1408 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
1409 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
1410
1411 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
1412 const auto& packet1 = packets[1];
1413 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001414 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001415 ASSERT_TRUE(packet1.has_frame_timeline_event());
1416
1417 const auto& event1 = packet1.frame_timeline_event();
1418 ASSERT_TRUE(event1.has_frame_end());
1419 const auto& expectedDisplayFrameEnd = event1.frame_end();
1420 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
1421
1422 // Packet - 2 : ActualDisplayFrameStart
1423 const auto& packet2 = packets[2];
1424 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001425 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001426 ASSERT_TRUE(packet2.has_frame_timeline_event());
1427
1428 const auto& event2 = packet2.frame_timeline_event();
1429 ASSERT_TRUE(event2.has_actual_display_frame_start());
1430 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1431 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1432
1433 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1434 const auto& packet3 = packets[3];
1435 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001436 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001437 ASSERT_TRUE(packet3.has_frame_timeline_event());
1438
1439 const auto& event3 = packet3.frame_timeline_event();
1440 ASSERT_TRUE(event3.has_frame_end());
1441 const auto& actualDisplayFrameEnd = event3.frame_end();
1442 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001443}
1444
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001445TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1446 auto tracingSession = getTracingSessionForTest();
1447 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1448
1449 tracingSession->StartBlocking();
1450 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1451 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001452 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001453
Ady Abraham57a8ab42023-01-26 15:28:19 -08001454 // Add an empty surface frame so that display frame would get traced.
1455 addEmptySurfaceFrame();
1456
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001457 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001458 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001459 mFrameTimeline->setSfPresent(26, presentFence1);
1460 presentFence1->signalForTest(31);
1461
1462 int64_t traceCookie = snoopCurrentTraceCookie();
1463
1464 auto protoActualDisplayFrameStart =
1465 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1466 kSurfaceFlingerPid,
1467 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001468 false, FrameTimelineEvent::JANK_UNKNOWN,
Ying Wei96eb5352023-11-21 17:37:21 +00001469 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001470 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001471 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1472
1473 addEmptyDisplayFrame();
1474 flushTrace();
1475 tracingSession->StopBlocking();
1476
1477 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1478 // Only actual timeline packets should be in the trace
1479 EXPECT_EQ(packets.size(), 2u);
1480
1481 // Packet - 0 : ActualDisplayFrameStart
1482 const auto& packet0 = packets[0];
1483 ASSERT_TRUE(packet0.has_timestamp());
1484 EXPECT_EQ(packet0.timestamp(), 20u);
1485 ASSERT_TRUE(packet0.has_frame_timeline_event());
1486
1487 const auto& event0 = packet0.frame_timeline_event();
1488 ASSERT_TRUE(event0.has_actual_display_frame_start());
1489 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1490 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1491
1492 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1493 const auto& packet1 = packets[1];
1494 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001495 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001496 ASSERT_TRUE(packet1.has_frame_timeline_event());
1497
1498 const auto& event1 = packet1.frame_timeline_event();
1499 ASSERT_TRUE(event1.has_frame_end());
1500 const auto& actualDisplayFrameEnd = event1.frame_end();
1501 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1502}
1503
Adithya Srinivasan01189672020-10-20 14:23:05 -07001504TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1505 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001506 // Layer specific increment
Edgar Arriaga631e4252023-03-02 02:11:24 +00001507 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001508 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1509 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1510
1511 tracingSession->StartBlocking();
1512 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1513 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001514
Huihong Luo3bdef862022-03-03 11:57:19 -08001515 FrameTimelineInfo ftInfo;
1516 ftInfo.vsyncId = surfaceFrameToken;
1517 ftInfo.inputEventId = sInputEventId;
1518
Adithya Srinivasan01189672020-10-20 14:23:05 -07001519 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001520 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1521 sLayerNameOne, sLayerNameOne,
1522 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001523 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001524 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1525 sLayerNameOne, sLayerNameOne,
1526 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001527 surfaceFrame1->setActualQueueTime(10);
1528 surfaceFrame1->setDropTime(15);
1529
1530 surfaceFrame2->setActualQueueTime(15);
1531 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001532
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001533 // First 2 cookies will be used by the DisplayFrame
1534 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1535
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001536 auto protoDroppedSurfaceFrameExpectedStart =
1537 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1538 displayFrameToken1, sPidOne, sLayerNameOne);
1539 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1540 auto protoDroppedSurfaceFrameActualStart =
1541 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1542 displayFrameToken1, sPidOne, sLayerNameOne,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001543 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1544 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001545 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001546 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001547 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001548
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001549 auto protoPresentedSurfaceFrameExpectedStart =
1550 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1551 displayFrameToken1, sPidOne, sLayerNameOne);
1552 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1553 auto protoPresentedSurfaceFrameActualStart =
1554 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1555 displayFrameToken1, sPidOne, sLayerNameOne,
1556 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001557 FrameTimelineEvent::JANK_NONE,
Ying Wei96eb5352023-11-21 17:37:21 +00001558 FrameTimelineEvent::SEVERITY_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001559 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001560 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001561
1562 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001563 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001564 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1565 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001566 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001567 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001568 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001569 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001570
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001571 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001572 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001573 tracingSession->StopBlocking();
1574
1575 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001576 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1577 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001578
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001579 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001580 const auto& packet4 = packets[4];
1581 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001582 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001583 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001584
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001585 const auto& event4 = packet4.frame_timeline_event();
1586 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001587 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1588 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001589
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001590 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001591 const auto& packet5 = packets[5];
1592 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001593 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001594 ASSERT_TRUE(packet5.has_frame_timeline_event());
1595
1596 const auto& event5 = packet5.frame_timeline_event();
1597 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001598 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1599 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001600
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001601 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001602 const auto& packet6 = packets[6];
1603 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001604 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001605 ASSERT_TRUE(packet6.has_frame_timeline_event());
1606
1607 const auto& event6 = packet6.frame_timeline_event();
1608 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001609 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1610 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001611
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001612 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001613 const auto& packet7 = packets[7];
1614 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001615 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001616 ASSERT_TRUE(packet7.has_frame_timeline_event());
1617
1618 const auto& event7 = packet7.frame_timeline_event();
1619 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001620 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1621 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1622
1623 // Packet - 8 : ExpectedSurfaceFrameStart2
1624 const auto& packet8 = packets[8];
1625 ASSERT_TRUE(packet8.has_timestamp());
1626 EXPECT_EQ(packet8.timestamp(), 10u);
1627 ASSERT_TRUE(packet8.has_frame_timeline_event());
1628
1629 const auto& event8 = packet8.frame_timeline_event();
1630 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1631 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1632 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1633
1634 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1635 const auto& packet9 = packets[9];
1636 ASSERT_TRUE(packet9.has_timestamp());
1637 EXPECT_EQ(packet9.timestamp(), 25u);
1638 ASSERT_TRUE(packet9.has_frame_timeline_event());
1639
1640 const auto& event9 = packet9.frame_timeline_event();
1641 ASSERT_TRUE(event9.has_frame_end());
1642 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1643 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1644
1645 // Packet - 10 : ActualSurfaceFrameStart2
1646 const auto& packet10 = packets[10];
1647 ASSERT_TRUE(packet10.has_timestamp());
1648 EXPECT_EQ(packet10.timestamp(), 10u);
1649 ASSERT_TRUE(packet10.has_frame_timeline_event());
1650
1651 const auto& event10 = packet10.frame_timeline_event();
1652 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1653 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1654 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1655
1656 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1657 const auto& packet11 = packets[11];
1658 ASSERT_TRUE(packet11.has_timestamp());
1659 EXPECT_EQ(packet11.timestamp(), 20u);
1660 ASSERT_TRUE(packet11.has_frame_timeline_event());
1661
1662 const auto& event11 = packet11.frame_timeline_event();
1663 ASSERT_TRUE(event11.has_frame_end());
1664 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1665 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1666}
1667
Ady Abrahame43ff722022-02-15 14:44:25 -08001668TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredIsAppMissedDeadline) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001669 auto tracingSession = getTracingSessionForTest();
1670 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1671
1672 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001673 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1674 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1675 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001676 int64_t surfaceFrameToken =
1677 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1678
1679 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001680 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001681 FrameTimelineInfo ftInfo;
1682 ftInfo.vsyncId = surfaceFrameToken;
1683 ftInfo.inputEventId = 0;
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001684 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001685 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1686 sLayerNameOne, sLayerNameOne,
1687 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001688 surfaceFrame1->setActualQueueTime(appEndTime);
1689 surfaceFrame1->setAcquireFenceTime(appEndTime);
1690
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001691 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1692 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1693 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001694 int64_t displayFrameToken =
1695 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1696
1697 // First 2 cookies will be used by the DisplayFrame
1698 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1699
1700 auto protoActualSurfaceFrameStart =
1701 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1702 displayFrameToken, sPidOne, sLayerNameOne,
1703 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Ady Abrahame43ff722022-02-15 14:44:25 -08001704 false, FrameTimelineEvent::JANK_APP_DEADLINE_MISSED,
Ying Wei96eb5352023-11-21 17:37:21 +00001705 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001706 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001707 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1708
1709 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001710 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001711 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1712 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1713 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1714 presentFence1->signalForTest(sfPresentTime);
1715
1716 addEmptyDisplayFrame();
1717 flushTrace();
1718 tracingSession->StopBlocking();
1719
1720 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1721 // Display Frame 4 packets + SurfaceFrame 2 packets
1722 ASSERT_EQ(packets.size(), 6u);
1723
1724 // Packet - 4 : ActualSurfaceFrameStart
1725 const auto& packet4 = packets[4];
1726 ASSERT_TRUE(packet4.has_timestamp());
1727 EXPECT_EQ(packet4.timestamp(),
1728 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1729 ASSERT_TRUE(packet4.has_frame_timeline_event());
1730
1731 const auto& event4 = packet4.frame_timeline_event();
1732 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1733 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1734 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1735
1736 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1737 const auto& packet5 = packets[5];
1738 ASSERT_TRUE(packet5.has_timestamp());
1739 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1740 ASSERT_TRUE(packet5.has_frame_timeline_event());
1741
1742 const auto& event5 = packet5.frame_timeline_event();
1743 ASSERT_TRUE(event5.has_frame_end());
1744 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001745 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001746}
1747
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001748TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDroppedFramesTracedProperly) {
1749 auto tracingSession = getTracingSessionForTest();
1750 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1751
1752 tracingSession->StartBlocking();
1753 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1754 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1755 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
1756 int64_t surfaceFrameToken =
1757 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1758
1759 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001760 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001761 FrameTimelineInfo ftInfo;
1762 ftInfo.vsyncId = surfaceFrameToken;
1763 ftInfo.inputEventId = 0;
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001764 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001765 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1766 sLayerNameOne, sLayerNameOne,
1767 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001768
1769 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(22ms).count();
1770 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1771 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
1772 int64_t displayFrameToken =
1773 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1774
1775 // First 2 cookies will be used by the DisplayFrame
1776 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1777
1778 auto protoActualSurfaceFrameStart =
1779 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1780 displayFrameToken, sPidOne, sLayerNameOne,
1781 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001782 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001783 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001784 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001785 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1786
1787 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001788 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001789 surfaceFrame1->setDropTime(sfStartTime);
1790 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1791 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1792 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1793 presentFence1->signalForTest(sfPresentTime);
1794
1795 addEmptyDisplayFrame();
1796 flushTrace();
1797 tracingSession->StopBlocking();
1798
1799 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1800 // Display Frame 4 packets + SurfaceFrame 2 packets
1801 ASSERT_EQ(packets.size(), 6u);
1802
1803 // Packet - 4 : ActualSurfaceFrameStart
1804 const auto& packet4 = packets[4];
1805 ASSERT_TRUE(packet4.has_timestamp());
1806 EXPECT_EQ(packet4.timestamp(),
1807 static_cast<uint64_t>(sfStartTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1808 ASSERT_TRUE(packet4.has_frame_timeline_event());
1809
1810 const auto& event4 = packet4.frame_timeline_event();
1811 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1812 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1813 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1814
1815 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1816 const auto& packet5 = packets[5];
1817 ASSERT_TRUE(packet5.has_timestamp());
1818 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(sfStartTime));
1819 ASSERT_TRUE(packet5.has_frame_timeline_event());
1820
1821 const auto& event5 = packet5.frame_timeline_event();
1822 ASSERT_TRUE(event5.has_frame_end());
1823 const auto& actualSurfaceFrameEnd = event5.frame_end();
1824 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
1825}
1826
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001827// Tests for Jank classification
1828TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001829 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001830 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001831 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1832 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001833 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -08001834 FrameTimelineInfo ftInfo;
1835 ftInfo.vsyncId = surfaceFrameToken;
1836 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001837 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -08001838 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1839 sLayerNameOne, sLayerNameOne,
1840 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001841 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001842 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1843 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1844 mFrameTimeline->setSfPresent(26, presentFence1);
1845 auto displayFrame = getDisplayFrame(0);
1846 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1847 presentFence1->signalForTest(29);
1848
1849 // Fences haven't been flushed yet, so it should be 0
1850 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1851 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1852
1853 addEmptyDisplayFrame();
1854 displayFrame = getDisplayFrame(0);
1855
1856 // Fences have flushed, so the present timestamps should be updated
1857 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1858 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1859 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1860 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1861 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00001862 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::None);
Pascal Mütschardd56514e2024-05-24 17:37:13 +02001863
1864 auto jankData = getLayerOneJankData();
1865 EXPECT_EQ(jankData.size(), 1u);
1866 EXPECT_EQ(jankData[0].jankType, JankType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001867}
1868
1869TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001870 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001871 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001872 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1873 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001874 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001875 mFrameTimeline->setSfPresent(26, presentFence1);
1876 auto displayFrame = getDisplayFrame(0);
1877 presentFence1->signalForTest(30);
1878
1879 // Fences for the first frame haven't been flushed yet, so it should be 0
1880 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1881
1882 // Trigger a flush by finalizing the next DisplayFrame
1883 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001884 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001885 mFrameTimeline->setSfPresent(56, presentFence2);
1886 displayFrame = getDisplayFrame(0);
1887
1888 // Fences for the first frame have flushed, so the present timestamps should be updated
1889 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1890 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1891 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1892 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00001893 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001894
1895 // Fences for the second frame haven't been flushed yet, so it should be 0
1896 auto displayFrame2 = getDisplayFrame(1);
1897 presentFence2->signalForTest(65);
1898 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001899 addEmptyDisplayFrame();
1900 displayFrame2 = getDisplayFrame(1);
1901
1902 // Fences for the second frame have flushed, so the present timestamps should be updated
1903 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1904 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1905 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1906 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00001907 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001908}
1909
1910TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001911 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001912 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001913 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1914 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001915 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001916 mFrameTimeline->setSfPresent(26, presentFence1);
1917 auto displayFrame = getDisplayFrame(0);
1918 presentFence1->signalForTest(50);
1919
1920 // Fences for the first frame haven't been flushed yet, so it should be 0
1921 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1922
1923 // Trigger a flush by finalizing the next DisplayFrame
1924 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001925 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001926 mFrameTimeline->setSfPresent(56, presentFence2);
1927 displayFrame = getDisplayFrame(0);
1928
1929 // Fences for the first frame have flushed, so the present timestamps should be updated
1930 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1931 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1932 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1933 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00001934 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001935
1936 // Fences for the second frame haven't been flushed yet, so it should be 0
1937 auto displayFrame2 = getDisplayFrame(1);
1938 presentFence2->signalForTest(75);
1939 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1940
1941 addEmptyDisplayFrame();
1942 displayFrame2 = getDisplayFrame(1);
1943
1944 // Fences for the second frame have flushed, so the present timestamps should be updated
1945 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1946 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1947 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1948 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00001949 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001950}
1951
1952TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001953 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1954 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001955 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001956
1957 mFrameTimeline->setSfPresent(22, presentFence1);
1958 auto displayFrame = getDisplayFrame(0);
1959 presentFence1->signalForTest(28);
1960
1961 // Fences haven't been flushed yet, so it should be 0
1962 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1963
1964 addEmptyDisplayFrame();
1965 displayFrame = getDisplayFrame(0);
1966
1967 // Fences have flushed, so the present timestamps should be updated
1968 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1969 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1970 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1971 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00001972 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001973}
1974
1975TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001976 /*
1977 * Case 1 - cpu time > vsync period but combined time > deadline > deadline -> cpudeadlinemissed
1978 * Case 2 - cpu time < vsync period but combined time > deadline -> gpudeadlinemissed
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001979 * Case 3 - previous frame ran longer -> sf_stuffing
1980 * Case 4 - Long cpu under SF stuffing -> cpudeadlinemissed
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001981 */
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001982 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001983 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001984 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1985 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001986 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1987 auto gpuFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001988 auto gpuFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1989 auto gpuFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001990 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001991 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001992 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1993 int64_t sfToken4 = mTokenManager->generateTokenForPredictions({112, 120, 120});
1994
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001995 // case 1 - cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001996 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001997 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
1998 auto displayFrame0 = getDisplayFrame(0);
1999 gpuFence1->signalForTest(36);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002000 presentFence1->signalForTest(52);
2001
2002 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00002003 EXPECT_EQ(displayFrame0->getActuals().presentTime, 0);
2004
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002005 // case 2 - cpu time = 56 - 52 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002006 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00002007 mFrameTimeline->setSfPresent(56, presentFence2, gpuFence2);
2008 auto displayFrame1 = getDisplayFrame(1);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002009 gpuFence2->signalForTest(76);
2010 presentFence2->signalForTest(90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00002011
2012 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2013 // Fences have flushed for first displayFrame, so the present timestamps should be updated
2014 EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
2015 EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2016 EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Rachel Lee94917b32022-03-18 17:52:09 -07002017 EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002018 EXPECT_EQ(displayFrame0->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002019
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002020 // case 3 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002021 mFrameTimeline->setSfWakeUp(sfToken3, 106, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002022 mFrameTimeline->setSfPresent(112, presentFence3, gpuFence3);
2023 auto displayFrame2 = getDisplayFrame(2);
2024 gpuFence3->signalForTest(116);
2025 presentFence3->signalForTest(120);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002026
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002027 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00002028 // Fences have flushed for second displayFrame, so the present timestamps should be updated
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002029 EXPECT_EQ(displayFrame1->getActuals().presentTime, 90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00002030 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2031 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2032 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002033 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002034
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002035 // case 4 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002036 mFrameTimeline->setSfWakeUp(sfToken4, 120, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002037 mFrameTimeline->setSfPresent(140, presentFence4, gpuFence4);
2038 auto displayFrame3 = getDisplayFrame(3);
2039 gpuFence4->signalForTest(156);
2040 presentFence4->signalForTest(180);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002041
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002042 EXPECT_EQ(displayFrame3->getActuals().presentTime, 0);
2043 // Fences have flushed for third displayFrame, so the present timestamps should be updated
2044 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
2045 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2046 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2047 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00002048 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002049
2050 addEmptyDisplayFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002051
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002052 // Fences have flushed for third displayFrame, so the present timestamps should be updated
2053 EXPECT_EQ(displayFrame3->getActuals().presentTime, 180);
2054 EXPECT_EQ(displayFrame3->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2055 EXPECT_EQ(displayFrame3->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2056 EXPECT_EQ(displayFrame3->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002057 EXPECT_EQ(displayFrame3->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002058}
2059
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002060TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08002061 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002062 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002063 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
2064 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002065 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
2066 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08002067 FrameTimelineInfo ftInfo;
2068 ftInfo.vsyncId = surfaceFrameToken1;
2069 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002070 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002071 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2072 sLayerNameOne, sLayerNameOne,
2073 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002074 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002075 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002076 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2077 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002078 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002079 auto displayFrame1 = getDisplayFrame(0);
2080 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2081 presentFence1->signalForTest(30);
2082
2083 // Fences for the first frame haven't been flushed yet, so it should be 0
2084 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2085 auto actuals1 = presentedSurfaceFrame1.getActuals();
2086 EXPECT_EQ(actuals1.presentTime, 0);
2087
2088 // Trigger a flush by finalizing the next DisplayFrame
2089 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002090 FrameTimelineInfo ftInfo2;
2091 ftInfo2.vsyncId = surfaceFrameToken2;
2092 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002093 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002094 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2095 sLayerNameOne, sLayerNameOne,
2096 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002097 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002098 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002099 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2100 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002101 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002102 auto displayFrame2 = getDisplayFrame(1);
2103 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2104
2105 // Fences for the first frame have flushed, so the present timestamps should be updated
2106 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
2107 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2108 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2109 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00002110 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002111
2112 actuals1 = presentedSurfaceFrame1.getActuals();
2113 EXPECT_EQ(actuals1.presentTime, 30);
2114 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2115 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2116 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00002117 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002118
2119 // Fences for the second frame haven't been flushed yet, so it should be 0
2120 presentFence2->signalForTest(65);
2121 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2122 auto actuals2 = presentedSurfaceFrame2.getActuals();
2123 EXPECT_EQ(actuals2.presentTime, 0);
2124
Alec Mouri363faf02021-01-29 16:34:55 -08002125 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
2126
2127 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002128 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
2129 sLayerNameOne, sGameMode,
2130 JankType::PredictionError, -3, 5,
2131 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08002132
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002133 addEmptyDisplayFrame();
2134
2135 // Fences for the second frame have flushed, so the present timestamps should be updated
2136 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
2137 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2138 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2139 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002140 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002141
2142 actuals2 = presentedSurfaceFrame2.getActuals();
2143 EXPECT_EQ(actuals2.presentTime, 65);
2144 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2145 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2146 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002147 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002148}
2149
2150TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08002151 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002152 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002153 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
2154 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002155 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
2156 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08002157 FrameTimelineInfo ftInfo;
2158 ftInfo.vsyncId = surfaceFrameToken1;
2159 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002160 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002161 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2162 sLayerNameOne, sLayerNameOne,
2163 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002164 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002165 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002166 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2167 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2168 mFrameTimeline->setSfPresent(26, presentFence1);
2169 auto displayFrame1 = getDisplayFrame(0);
2170 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2171 presentFence1->signalForTest(50);
2172
2173 // Fences for the first frame haven't been flushed yet, so it should be 0
2174 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2175 auto actuals1 = presentedSurfaceFrame1.getActuals();
2176 EXPECT_EQ(actuals1.presentTime, 0);
2177
2178 // Trigger a flush by finalizing the next DisplayFrame
2179 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002180 FrameTimelineInfo ftInfo2;
2181 ftInfo2.vsyncId = surfaceFrameToken2;
2182 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002183 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002184 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2185 sLayerNameOne, sLayerNameOne,
2186 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002187 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002188 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002189 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2190 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002191 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002192 auto displayFrame2 = getDisplayFrame(1);
2193 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2194
2195 // Fences for the first frame have flushed, so the present timestamps should be updated
2196 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
2197 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2198 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2199 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002200 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002201
2202 actuals1 = presentedSurfaceFrame1.getActuals();
2203 EXPECT_EQ(actuals1.presentTime, 50);
2204 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2205 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2206 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002207 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002208
2209 // Fences for the second frame haven't been flushed yet, so it should be 0
2210 presentFence2->signalForTest(86);
2211 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2212 auto actuals2 = presentedSurfaceFrame2.getActuals();
2213 EXPECT_EQ(actuals2.presentTime, 0);
2214
Alec Mouri363faf02021-01-29 16:34:55 -08002215 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
2216
2217 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002218 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
2219 sLayerNameOne, sGameMode,
2220 JankType::PredictionError, -3, 5,
2221 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08002222
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002223 addEmptyDisplayFrame();
2224
2225 // Fences for the second frame have flushed, so the present timestamps should be updated
2226 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
2227 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2228 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2229 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002230 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002231
2232 actuals2 = presentedSurfaceFrame2.getActuals();
2233 EXPECT_EQ(actuals2.presentTime, 86);
2234 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2235 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2236 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002237 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002238}
2239
2240TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08002241 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08002242
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002243 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002244 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002245 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -08002246 FrameTimelineInfo ftInfo;
2247 ftInfo.vsyncId = surfaceFrameToken1;
2248 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002249 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002250 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2251 sLayerNameOne, sLayerNameOne,
2252 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002253 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002254 mFrameTimeline->setSfWakeUp(sfToken1, 42, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002255 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2256 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2257 mFrameTimeline->setSfPresent(46, presentFence1);
2258 auto displayFrame1 = getDisplayFrame(0);
2259 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2260 presentFence1->signalForTest(50);
2261
2262 // Fences for the first frame haven't been flushed yet, so it should be 0
2263 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2264 auto actuals1 = presentedSurfaceFrame1.getActuals();
2265 EXPECT_EQ(actuals1.presentTime, 0);
2266
2267 addEmptyDisplayFrame();
2268
2269 // Fences for the first frame have flushed, so the present timestamps should be updated
2270 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
2271 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2272 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2273 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002274 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002275
2276 actuals1 = presentedSurfaceFrame1.getActuals();
2277 EXPECT_EQ(actuals1.presentTime, 50);
2278 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2279 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2280 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +00002281 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002282}
2283
2284TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002285 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as only
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002286 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002287 // jank to the SurfaceFrame along with AppDeadlineMissed.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002288
Alec Mouri363faf02021-01-29 16:34:55 -08002289 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002290 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002291 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
2292 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002293 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
2294 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
Huihong Luo3bdef862022-03-03 11:57:19 -08002295 FrameTimelineInfo ftInfo;
2296 ftInfo.vsyncId = surfaceFrameToken1;
2297 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002298 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002299 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2300 sLayerNameOne, sLayerNameOne,
2301 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002302 surfaceFrame1->setAcquireFenceTime(26);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002303 mFrameTimeline->setSfWakeUp(sfToken1, 32, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002304 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2305 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2306 mFrameTimeline->setSfPresent(36, presentFence1);
2307 auto displayFrame1 = getDisplayFrame(0);
2308 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2309 presentFence1->signalForTest(40);
2310
2311 // Fences for the first frame haven't been flushed yet, so it should be 0
2312 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2313 auto actuals1 = presentedSurfaceFrame1.getActuals();
2314 EXPECT_EQ(actuals1.presentTime, 0);
2315
2316 // Trigger a flush by finalizing the next DisplayFrame
2317 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002318 FrameTimelineInfo ftInfo2;
2319 ftInfo2.vsyncId = surfaceFrameToken2;
2320 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002321 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002322 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2323 sLayerNameOne, sLayerNameOne,
2324 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002325 surfaceFrame2->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002326 mFrameTimeline->setSfWakeUp(sfToken2, 43, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002327 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2328 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2329 mFrameTimeline->setSfPresent(56, presentFence2);
2330 auto displayFrame2 = getDisplayFrame(1);
2331 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2332
2333 // Fences for the first frame have flushed, so the present timestamps should be updated
2334 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
2335 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2336 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2337 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002338 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002339
2340 actuals1 = presentedSurfaceFrame1.getActuals();
2341 EXPECT_EQ(actuals1.presentTime, 40);
2342 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2343 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2344 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002345 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002346
2347 // Fences for the second frame haven't been flushed yet, so it should be 0
2348 presentFence2->signalForTest(60);
2349 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2350 auto actuals2 = presentedSurfaceFrame2.getActuals();
2351 EXPECT_EQ(actuals2.presentTime, 0);
2352
2353 addEmptyDisplayFrame();
2354
2355 // Fences for the second frame have flushed, so the present timestamps should be updated
2356 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
2357 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2358 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2359 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002360 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002361
2362 actuals2 = presentedSurfaceFrame2.getActuals();
2363 EXPECT_EQ(actuals2.presentTime, 60);
2364 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2365 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002366 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2367 JankType::SurfaceFlingerCpuDeadlineMissed | JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002368 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002369}
2370
2371TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002372 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08002373 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002374 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2375 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2376 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2377
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002378 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2379 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Huihong Luo3bdef862022-03-03 11:57:19 -08002380 FrameTimelineInfo ftInfo;
2381 ftInfo.vsyncId = surfaceFrameToken1;
2382 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002383 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002384 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2385 sLayerNameOne, sLayerNameOne,
2386 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002387 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002388 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002389 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2390 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2391 mFrameTimeline->setSfPresent(56, presentFence1);
2392 auto displayFrame1 = getDisplayFrame(0);
2393 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2394 presentFence1->signalForTest(60);
2395
2396 // Fences for the first frame haven't been flushed yet, so it should be 0
2397 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2398 auto actuals1 = presentedSurfaceFrame1.getActuals();
2399 EXPECT_EQ(actuals1.presentTime, 0);
2400
2401 // Trigger a flush by finalizing the next DisplayFrame
2402 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002403 FrameTimelineInfo ftInfo2;
2404 ftInfo2.vsyncId = surfaceFrameToken2;
2405 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002406 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002407 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2408 sLayerNameOne, sLayerNameOne,
2409 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002410 surfaceFrame2->setAcquireFenceTime(84);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002411 mFrameTimeline->setSfWakeUp(sfToken2, 112, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002412 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2413 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2414 mFrameTimeline->setSfPresent(116, presentFence2);
2415 auto displayFrame2 = getDisplayFrame(1);
2416 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2417 presentFence2->signalForTest(120);
2418
2419 // Fences for the first frame have flushed, so the present timestamps should be updated
2420 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2421 actuals1 = presentedSurfaceFrame1.getActuals();
2422 EXPECT_EQ(actuals1.endTime, 50);
2423 EXPECT_EQ(actuals1.presentTime, 60);
2424
2425 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2426 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2427 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002428 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002429
2430 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2431 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2432 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002433 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002434
2435 // Fences for the second frame haven't been flushed yet, so it should be 0
2436 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2437 auto actuals2 = presentedSurfaceFrame2.getActuals();
2438 EXPECT_EQ(actuals2.presentTime, 0);
2439
2440 addEmptyDisplayFrame();
2441
2442 // Fences for the second frame have flushed, so the present timestamps should be updated
2443 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
2444 actuals2 = presentedSurfaceFrame2.getActuals();
2445 EXPECT_EQ(actuals2.presentTime, 120);
2446
2447 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2448 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2449 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002450 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002451
2452 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2453 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2454 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2455 JankType::AppDeadlineMissed | JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00002456 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002457}
Alec Mouriadebf5c2021-01-05 12:57:36 -08002458
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002459TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
2460 // Layer specific increment
2461 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
2462 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2463 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2464 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2465
2466 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2467 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -08002468 FrameTimelineInfo ftInfo;
2469 ftInfo.vsyncId = surfaceFrameToken1;
2470 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002471 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002472 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2473 sLayerNameOne, sLayerNameOne,
2474 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002475 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002476 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002477 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2478 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2479 mFrameTimeline->setSfPresent(56, presentFence1);
2480 auto displayFrame1 = getDisplayFrame(0);
2481 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2482 presentFence1->signalForTest(60);
2483
2484 // Fences for the first frame haven't been flushed yet, so it should be 0
2485 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2486 auto actuals1 = presentedSurfaceFrame1.getActuals();
2487 EXPECT_EQ(actuals1.presentTime, 0);
2488
2489 // Trigger a flush by finalizing the next DisplayFrame
2490 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002491 FrameTimelineInfo ftInfo2;
2492 ftInfo2.vsyncId = surfaceFrameToken2;
2493 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002494 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002495 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2496 sLayerNameOne, sLayerNameOne,
2497 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002498 surfaceFrame2->setAcquireFenceTime(80);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002499 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002500 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
2501 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2502 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2503 mFrameTimeline->setSfPresent(86, presentFence2);
2504 auto displayFrame2 = getDisplayFrame(1);
2505 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2506 presentFence2->signalForTest(90);
2507
2508 // Fences for the first frame have flushed, so the present timestamps should be updated
2509 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2510 actuals1 = presentedSurfaceFrame1.getActuals();
2511 EXPECT_EQ(actuals1.endTime, 50);
2512 EXPECT_EQ(actuals1.presentTime, 60);
2513
2514 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2515 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2516 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002517 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002518
2519 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2520 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2521 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002522 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002523
2524 // Fences for the second frame haven't been flushed yet, so it should be 0
2525 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2526 auto actuals2 = presentedSurfaceFrame2.getActuals();
2527 EXPECT_EQ(actuals2.presentTime, 0);
2528
2529 addEmptyDisplayFrame();
2530
2531 // Fences for the second frame have flushed, so the present timestamps should be updated
2532 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2533 actuals2 = presentedSurfaceFrame2.getActuals();
2534 EXPECT_EQ(actuals2.presentTime, 90);
2535
2536 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2537 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2538 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002539 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002540
2541 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2542 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2543 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00002544 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002545}
2546
Rachel Lee94917b32022-03-18 17:52:09 -07002547TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent_GpuAndCpuMiss) {
2548 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2549 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2550 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2551 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2552 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2553
2554 // Case 1: cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002555 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Rachel Lee94917b32022-03-18 17:52:09 -07002556 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
2557 auto displayFrame = getDisplayFrame(0);
2558 gpuFence1->signalForTest(36);
2559 presentFence1->signalForTest(52);
2560
2561 // Fences haven't been flushed yet, so it should be 0
2562 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
2563
2564 addEmptyDisplayFrame();
2565 displayFrame = getDisplayFrame(0);
2566
2567 // Fences have flushed, so the present timestamps should be updated
2568 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
2569 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2570 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2571 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002572 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Full);
Rachel Lee94917b32022-03-18 17:52:09 -07002573
2574 // Case 2: No GPU fence so it will not use GPU composition.
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002575 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Rachel Lee94917b32022-03-18 17:52:09 -07002576 mFrameTimeline->setSfPresent(66, presentFence2);
2577 auto displayFrame2 = getDisplayFrame(2); // 2 because of previous empty frame
2578 presentFence2->signalForTest(90);
2579
2580 // Fences for the frame haven't been flushed yet, so it should be 0
2581 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2582
2583 addEmptyDisplayFrame();
2584
2585 // Fences have flushed, so the present timestamps should be updated
2586 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2587 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2588 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2589 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002590 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Rachel Lee94917b32022-03-18 17:52:09 -07002591}
2592
Ady Abrahamfcb16862022-10-10 14:35:21 -07002593TEST_F(FrameTimelineTest, jankClassification_presentFenceError) {
2594 auto erroneousPresentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2595 auto erroneousPresentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2596 auto validPresentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2597 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2598 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2599 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({72, 80, 80});
2600
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002601 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002602 mFrameTimeline->setSfPresent(26, erroneousPresentFence1);
2603
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002604 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002605 mFrameTimeline->setSfPresent(60, erroneousPresentFence2);
2606
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002607 mFrameTimeline->setSfWakeUp(sfToken3, 72, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002608 mFrameTimeline->setSfPresent(80, validPresentFence);
2609
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002610 erroneousPresentFence2->signalForTest(2);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002611 validPresentFence->signalForTest(80);
2612
2613 addEmptyDisplayFrame();
2614
2615 {
2616 auto displayFrame = getDisplayFrame(0);
2617 EXPECT_EQ(displayFrame->getActuals().presentTime, 26);
2618 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2619 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002620 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002621 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002622 }
2623 {
2624 auto displayFrame = getDisplayFrame(1);
2625 EXPECT_EQ(displayFrame->getActuals().presentTime, 60);
2626 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2627 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002628 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002629 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002630 }
2631 {
2632 auto displayFrame = getDisplayFrame(2);
2633 EXPECT_EQ(displayFrame->getActuals().presentTime, 80);
2634 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2635 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2636 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002637 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::None);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002638 }
2639}
2640
Alec Mouriadebf5c2021-01-05 12:57:36 -08002641TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
2642 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
2643}
2644
2645TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002646 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002647
2648 auto surfaceFrame1 =
2649 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002650 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002651 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002652 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2653 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2654 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2655 presentFence1->signalForTest(oneHundredMs);
2656 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2657
2658 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2659}
2660
2661TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002662 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2663 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002664 auto surfaceFrame1 =
2665 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002666 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002667 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002668 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2669 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2670 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2671 presentFence1->signalForTest(oneHundredMs);
2672 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2673
2674 auto surfaceFrame2 =
2675 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002676 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002677 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002678 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2679 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2680 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2681 presentFence2->signalForTest(twoHundredMs);
2682 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2683
2684 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
2685}
2686
2687TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002688 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2689 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002690 auto surfaceFrame1 =
2691 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002692 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002693 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002694 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2695 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2696 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2697 presentFence1->signalForTest(oneHundredMs);
2698 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2699
2700 auto surfaceFrame2 =
2701 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002702 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002703 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002704 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2705 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2706 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2707 presentFence2->signalForTest(twoHundredMs);
2708 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2709
2710 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
2711}
2712
2713TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002714 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2715 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002716 auto surfaceFrame1 =
2717 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002718 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002719 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002720 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2721 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2722 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2723 presentFence1->signalForTest(oneHundredMs);
2724 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2725
2726 auto surfaceFrame2 =
2727 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002728 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002729 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002730 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2731 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2732 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2733 presentFence2->signalForTest(twoHundredMs);
2734 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2735
2736 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2737}
2738
2739TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002740 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2741 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2742 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2743 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2744 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002745 auto surfaceFrame1 =
2746 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002747 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002748 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002749 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2750 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2751 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2752 presentFence1->signalForTest(oneHundredMs);
2753 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2754
2755 auto surfaceFrame2 =
2756 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002757 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002758 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002759 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2760 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2761 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2762 presentFence2->signalForTest(twoHundredMs);
2763 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2764
2765 auto surfaceFrame3 =
2766 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002767 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002768 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002769 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2770 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2771 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2772 presentFence3->signalForTest(threeHundredMs);
2773 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2774
2775 auto surfaceFrame4 =
2776 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002777 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002778 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002779 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2780 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2781 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2782 presentFence4->signalForTest(fiveHundredMs);
2783 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2784
2785 auto surfaceFrame5 =
2786 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002787 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002788 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002789 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2790 // Dropped frames will be excluded from fps computation
2791 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2792 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2793 presentFence5->signalForTest(sixHundredMs);
2794 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2795
2796 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2797}
2798
ramindaniea2bb822022-06-27 19:52:10 +00002799TEST_F(FrameTimelineTest, getMinTime) {
2800 // Use SurfaceFrame::getBaseTime to test the getMinTime.
2801 FrameTimelineInfo ftInfo;
2802
2803 // Valid prediction state test.
2804 ftInfo.vsyncId = 0L;
2805 mTokenManager->generateTokenForPredictions({10});
2806 auto surfaceFrame =
2807 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2808 sLayerNameOne, sLayerNameOne,
2809 /*isBuffer*/ true, sGameMode);
2810 ASSERT_EQ(surfaceFrame->getBaseTime(), 10);
2811
2812 // Test prediction state which is not valid.
2813 ftInfo.vsyncId = FrameTimelineInfo::INVALID_VSYNC_ID;
2814 surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2815 sLayerNameOne, sLayerNameOne,
2816 /*isBuffer*/ true, sGameMode);
2817 // Start time test.
2818 surfaceFrame->setActualStartTime(200);
2819 ASSERT_EQ(surfaceFrame->getBaseTime(), 200);
2820
2821 // End time test.
2822 surfaceFrame->setAcquireFenceTime(100);
2823 ASSERT_EQ(surfaceFrame->getBaseTime(), 100);
2824
2825 // Present time test.
2826 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2827 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2828 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2829 presentFence->signalForTest(std::chrono::nanoseconds(50ns).count());
2830 mFrameTimeline->setSfPresent(50, presentFence);
2831 ASSERT_EQ(surfaceFrame->getBaseTime(), 50);
2832}
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002833
2834TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingDisplayRate) {
2835 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2836 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2837 FrameTimelineInfo ftInfo;
2838 ftInfo.vsyncId = token1;
2839 ftInfo.inputEventId = sInputEventId;
2840 auto surfaceFrame =
2841 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2842 sLayerNameOne, sLayerNameOne,
2843 /*isBuffer*/ true, sGameMode);
2844
2845 mFrameTimeline->setSfWakeUp(token1, 20, RR_30, RR_11);
2846 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2847 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2848 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2849 mFrameTimeline->setSfPresent(50, presentFence1);
2850
2851 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 11);
2852}
2853
2854TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingAppFrameRate) {
2855 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2856 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2857 FrameTimelineInfo ftInfo;
2858 ftInfo.vsyncId = token1;
2859 ftInfo.inputEventId = sInputEventId;
2860 auto surfaceFrame =
2861 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2862 sLayerNameOne, sLayerNameOne,
2863 /*isBuffer*/ true, sGameMode);
2864 surfaceFrame->setRenderRate(RR_30);
2865 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
2866 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2867 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2868 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2869 mFrameTimeline->setSfPresent(50, presentFence1);
2870
2871 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 30);
2872}
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002873} // namespace android::frametimeline