blob: 08e426564aad9f3526a5061e82e0e814b5c3fd58 [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
Liz Prucka31b58c92024-11-08 21:13:44 +0000169 NO_THREAD_SAFETY_ANALYSIS
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000170 const std::map<int64_t, TimelineItem>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700171 return mTokenManager->mPredictions;
172 }
173
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000174 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700175 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
176 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
177 }
178
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000179 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
180
181 void flushTrace() {
182 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
183 FrameTimelineDataSource::Trace(
184 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
185 }
186
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200187 std::vector<gui::JankData> getLayerOneJankData() {
188 BackgroundExecutor::getLowPriorityInstance().flushQueue();
189 return JankTracker::getCollectedJankDataForTesting(sLayerIdOne);
190 }
191
192 std::vector<gui::JankData> getLayerTwoJankData() {
193 BackgroundExecutor::getLowPriorityInstance().flushQueue();
194 return JankTracker::getCollectedJankDataForTesting(sLayerIdTwo);
195 }
196
Alec Mouri9a29e672020-09-14 12:39:14 -0700197 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700198 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
199 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000200 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700201 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700202 uint32_t* maxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000203 size_t maxTokens;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000204 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasanead17162021-02-18 02:17:37 +0000205 static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan54996e22021-06-25 22:26:45 +0000206 static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(0ns).count();
Adithya Srinivasanead17162021-02-18 02:17:37 +0000207 static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800208 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
209 kDeadlineThreshold,
210 kStartThreshold};
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700211};
212
213TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
214 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000215 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000216 flushTokens();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700217 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
218 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
219
220 // token1 should have expired
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700221 EXPECT_EQ(predictions.has_value(), false);
222
223 predictions = mTokenManager->getPredictionsForToken(token2);
224 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
225}
226
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700227TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800228 auto surfaceFrame1 =
229 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000230 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000231 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -0800232 auto surfaceFrame2 =
233 mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000234 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000235 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700236 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
237 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
238}
239
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700240TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800241 auto surfaceFrame =
242 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000243 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000244 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700245 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
246}
247
248TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
249 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000250 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -0800251 FrameTimelineInfo ftInfo;
252 ftInfo.vsyncId = token1;
253 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000254 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800255 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
256 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000257 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700258
259 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
260}
261
262TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
263 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800264 FrameTimelineInfo ftInfo;
265 ftInfo.vsyncId = token1;
266 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000267 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800268 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
269 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000270 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700271
272 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
273 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
274}
275
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000276TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
277 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
278 constexpr int32_t inputEventId = 1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800279 FrameTimelineInfo ftInfo;
280 ftInfo.vsyncId = token1;
281 ftInfo.inputEventId = inputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000282 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800283 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
284 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000285 /*isBuffer*/ true, sGameMode);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000286
287 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
288}
289
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700290TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
291 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700292 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800293 FrameTimelineInfo ftInfo;
294 ftInfo.vsyncId = token1;
295 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000296 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800297 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
298 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000299 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700300
301 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200302 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000303 surfaceFrame1->setDropTime(12);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800304 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
305 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700306 mFrameTimeline->setSfPresent(25, presentFence1);
307 presentFence1->signalForTest(30);
308
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000309 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700310
311 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
312 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000313 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
314 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700315 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
316}
317
318TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800319 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800320 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700321 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
322 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700323 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800324 FrameTimelineInfo ftInfo;
325 ftInfo.vsyncId = surfaceFrameToken1;
326 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700327 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800328 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
329 sLayerNameOne, sLayerNameOne,
330 /*isBuffer*/ true, sGameMode);
Alec Mouri9a29e672020-09-14 12:39:14 -0700331 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800332 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdTwo,
333 sLayerNameTwo, sLayerNameTwo,
334 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200335 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800336 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
337 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
338 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
339 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700340 mFrameTimeline->setSfPresent(26, presentFence1);
341 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800342 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
343 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700344 presentFence1->signalForTest(42);
345
346 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800347 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700348 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
349 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
350
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000351 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700352
353 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800354 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700355 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
356 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100357 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
Ying Wei96eb5352023-11-21 17:37:21 +0000358 EXPECT_NE(surfaceFrame1->getJankSeverityType(), std::nullopt);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100359 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Ying Wei96eb5352023-11-21 17:37:21 +0000360 EXPECT_NE(surfaceFrame2->getJankSeverityType(), std::nullopt);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200361
362 EXPECT_EQ(getLayerOneJankData().size(), 1u);
363 EXPECT_EQ(getLayerTwoJankData().size(), 1u);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700364}
365
Ady Abraham14beed72024-05-15 17:16:45 -0700366TEST_F(FrameTimelineTest, displayFrameSkippedComposition) {
367 // Layer specific increment
368 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(1);
369 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
370 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
371 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
372 FrameTimelineInfo ftInfo;
373 ftInfo.vsyncId = surfaceFrameToken1;
374 ftInfo.inputEventId = sInputEventId;
375 auto surfaceFrame1 =
376 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
377 sLayerNameOne, sLayerNameOne,
378 /*isBuffer*/ true, sGameMode);
379 auto surfaceFrame2 =
380 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdTwo,
381 sLayerNameTwo, sLayerNameTwo,
382 /*isBuffer*/ true, sGameMode);
383
384 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
385 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
386 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
387 mFrameTimeline->onCommitNotComposited();
388
389 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 30);
390 ASSERT_NE(surfaceFrame1->getJankType(), std::nullopt);
391 EXPECT_EQ(*surfaceFrame1->getJankType(), JankType::None);
392 ASSERT_NE(surfaceFrame1->getJankSeverityType(), std::nullopt);
393 EXPECT_EQ(*surfaceFrame1->getJankSeverityType(), JankSeverityType::None);
394
395 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
396 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
397 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
398 mFrameTimeline->setSfPresent(26, presentFence1);
399
400 auto displayFrame = getDisplayFrame(0);
401 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 0);
402 presentFence1->signalForTest(42);
403
404 // Fences haven't been flushed yet, so it should be 0
405 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
406 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
407
408 addEmptyDisplayFrame();
409
410 // Fences have flushed, so the present timestamps should be updated
411 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
412 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
413 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
414 EXPECT_NE(surfaceFrame2->getJankSeverityType(), std::nullopt);
415}
416
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700417TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
418 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
419 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800420 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800421 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800422 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700423 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700424 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
425 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
426 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
427 int64_t sfToken = mTokenManager->generateTokenForPredictions(
428 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800429 FrameTimelineInfo ftInfo;
430 ftInfo.vsyncId = surfaceFrameToken;
431 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700432 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800433 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000434 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000435 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200436 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800437 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
438 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700439 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
440 presentFence->signalForTest(32 + frameTimeFactor);
441 frameTimeFactor += 30;
442 }
443 auto displayFrame0 = getDisplayFrame(0);
444
445 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800446 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700447
448 // Add one more display frame
449 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
450 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
451 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
452 int64_t sfToken = mTokenManager->generateTokenForPredictions(
453 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800454 FrameTimelineInfo ftInfo;
455 ftInfo.vsyncId = surfaceFrameToken;
456 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700457 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800458 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
459 sLayerNameOne, sLayerNameOne,
460 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200461 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800462 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
463 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700464 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
465 presentFence->signalForTest(32 + frameTimeFactor);
466 displayFrame0 = getDisplayFrame(0);
467
468 // The window should have slided by 1 now and the previous 0th display frame
469 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800470 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200471
472 EXPECT_EQ(getLayerOneJankData().size(), *maxDisplayFrames);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700473}
474
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700475TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000476 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
477 "acquireFenceAfterQueue",
478 "acquireFenceAfterQueue",
479 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700480 surfaceFrame->setActualQueueTime(123);
481 surfaceFrame->setAcquireFenceTime(456);
482 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
483}
484
Vishnu Nairbd7d07e2024-07-08 13:37:11 -0700485TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceUnsignaled) {
486 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
487 "acquireFenceAfterQueue",
488 "acquireFenceAfterQueue",
489 /*isBuffer*/ true, sGameMode);
490 surfaceFrame->setActualQueueTime(123);
491 surfaceFrame->setAcquireFenceTime(Fence::SIGNAL_TIME_PENDING);
492 EXPECT_EQ(surfaceFrame->getActuals().endTime, 123);
493}
494
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700495TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000496 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
497 "acquireFenceAfterQueue",
498 "acquireFenceAfterQueue",
499 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700500 surfaceFrame->setActualQueueTime(456);
501 surfaceFrame->setAcquireFenceTime(123);
502 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
503}
504
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700505TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
506 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
507 presentFence->signalForTest(2);
508
509 // Size shouldn't exceed maxDisplayFrames - 64
510 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700511 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800512 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000513 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000514 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700515 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200516 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800517 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
518 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700519 mFrameTimeline->setSfPresent(27, presentFence);
520 }
521 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
522
523 // Increase the size to 256
524 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000525 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700526
527 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700528 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800529 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000530 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000531 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700532 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200533 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800534 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
535 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700536 mFrameTimeline->setSfPresent(27, presentFence);
537 }
538 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
539
540 // Shrink the size to 128
541 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000542 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700543
544 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700545 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800546 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000547 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000548 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700549 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200550 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800551 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
552 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700553 mFrameTimeline->setSfPresent(27, presentFence);
554 }
555 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
556}
Alec Mouri9a29e672020-09-14 12:39:14 -0700557
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000558TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200559 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000560
561 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
562 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
563 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800564 FrameTimelineInfo ftInfo;
565 ftInfo.vsyncId = surfaceFrameToken1;
566 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000567
568 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800569 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
570 sLayerNameOne, sLayerNameOne,
571 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200572 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000573 surfaceFrame1->setAcquireFenceTime(20);
574 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
575 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
576
577 mFrameTimeline->setSfPresent(59, presentFence1);
578 presentFence1->signalForTest(-1);
579 addEmptyDisplayFrame();
580
581 auto displayFrame0 = getDisplayFrame(0);
Ady Abrahamfcb16862022-10-10 14:35:21 -0700582 EXPECT_EQ(displayFrame0->getActuals().presentTime, 59);
Ady Abrahamb1e10d12023-03-13 15:23:54 -0700583 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +0000584 EXPECT_EQ(displayFrame0->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000585 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
586 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +0000587 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000588}
589
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800590// Tests related to TimeStats
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000591TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200592 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000593 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
594 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
595 int64_t surfaceFrameToken1 = -1;
596 int64_t sfToken1 = -1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800597 FrameTimelineInfo ftInfo;
598 ftInfo.vsyncId = surfaceFrameToken1;
599 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000600
601 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800602 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
603 sLayerNameOne, sLayerNameOne,
604 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200605 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000606 surfaceFrame1->setAcquireFenceTime(20);
607 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
608 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
609 presentFence1->signalForTest(70);
610
611 mFrameTimeline->setSfPresent(59, presentFence1);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200612
613 EXPECT_EQ(getLayerOneJankData().size(), 0u);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000614}
615
Alec Mouri9a29e672020-09-14 12:39:14 -0700616TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200617 Fps refreshRate = RR_11;
Alec Mouri9a29e672020-09-14 12:39:14 -0700618 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800619 incrementJankyFrames(
620 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000621 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000622 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800623 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700624 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000625 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
626 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800627 FrameTimelineInfo ftInfo;
628 ftInfo.vsyncId = surfaceFrameToken1;
629 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000630
Alec Mouri9a29e672020-09-14 12:39:14 -0700631 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800632 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
633 sLayerNameOne, sLayerNameOne,
634 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200635 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000636 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800637 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
638 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000639 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700640
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000641 mFrameTimeline->setSfPresent(62, presentFence1);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200642
643 auto jankData = getLayerOneJankData();
644 EXPECT_EQ(jankData.size(), 1u);
645 EXPECT_EQ(jankData[0].jankType, JankType::SurfaceFlingerCpuDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700646}
647
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000648TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfGpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200649 Fps refreshRate = RR_11;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000650 EXPECT_CALL(*mTimeStats,
651 incrementJankyFrames(
652 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000653 sLayerNameOne, sGameMode,
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000654 JankType::SurfaceFlingerGpuDeadlineMissed, 4, 10,
655 0}));
656 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
657 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
658 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
659 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800660 FrameTimelineInfo ftInfo;
661 ftInfo.vsyncId = surfaceFrameToken1;
662 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000663
664 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800665 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
666 sLayerNameOne, sLayerNameOne,
667 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200668 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000669 surfaceFrame1->setAcquireFenceTime(20);
670 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
671 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
672 gpuFence1->signalForTest(64);
673 presentFence1->signalForTest(70);
674
675 mFrameTimeline->setSfPresent(59, presentFence1, gpuFence1);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200676
677 auto jankData = getLayerOneJankData();
678 EXPECT_EQ(jankData.size(), 1u);
679 EXPECT_EQ(jankData[0].jankType, JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000680}
681
Alec Mouri9a29e672020-09-14 12:39:14 -0700682TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200683 Fps refreshRate = RR_30;
Alec Mouri9a29e672020-09-14 12:39:14 -0700684 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800685 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000686 sLayerNameOne, sGameMode,
687 JankType::DisplayHAL, -4, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800688
Alec Mouri9a29e672020-09-14 12:39:14 -0700689 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000690 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
691 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800692 FrameTimelineInfo ftInfo;
693 ftInfo.vsyncId = surfaceFrameToken1;
694 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000695
Alec Mouri9a29e672020-09-14 12:39:14 -0700696 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800697 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
698 sLayerNameOne, sLayerNameOne,
699 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200700 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800701 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000702 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800703 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000704 presentFence1->signalForTest(90);
705 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800706 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +0000707 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200708
709 auto jankData = getLayerOneJankData();
710 EXPECT_EQ(jankData.size(), 1u);
711 EXPECT_EQ(jankData[0].jankType, JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700712}
713
714TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700715 Fps refreshRate = 11_Hz;
Alec Mouri9a29e672020-09-14 12:39:14 -0700716 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000717 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000718 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000719 JankType::AppDeadlineMissed, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000720 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700721 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000722 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
723 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800724 FrameTimelineInfo ftInfo;
725 ftInfo.vsyncId = surfaceFrameToken1;
726 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000727
Alec Mouri9a29e672020-09-14 12:39:14 -0700728 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800729 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
730 sLayerNameOne, sLayerNameOne,
731 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000732 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200733 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700734
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800735 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
736 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000737 presentFence1->signalForTest(90);
738 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100739
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800740 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000741 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Partial);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200742
743 auto jankData = getLayerOneJankData();
744 EXPECT_EQ(jankData.size(), 1u);
745 EXPECT_EQ(jankData[0].jankType, JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700746}
747
Adithya Srinivasanead17162021-02-18 02:17:37 +0000748TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000749 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000750 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000751 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000752 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000753 JankType::SurfaceFlingerScheduling,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000754 -4, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000755 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000756 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
757 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800758 FrameTimelineInfo ftInfo;
759 ftInfo.vsyncId = surfaceFrameToken1;
760 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000761
Adithya Srinivasanead17162021-02-18 02:17:37 +0000762 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800763 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
764 sLayerNameOne, sLayerNameOne,
765 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000766 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200767 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000768
769 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
770 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000771 presentFence1->signalForTest(60);
772 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000773
774 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +0000775 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200776
777 auto jankData = getLayerOneJankData();
778 EXPECT_EQ(jankData.size(), 1u);
779 EXPECT_EQ(jankData[0].jankType, JankType::SurfaceFlingerScheduling);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000780}
781
782TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000783 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000784 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000785 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000786 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000787 JankType::PredictionError, -4, 5,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000788 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000789 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000790 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
791 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800792 FrameTimelineInfo ftInfo;
793 ftInfo.vsyncId = surfaceFrameToken1;
794 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000795
Adithya Srinivasanead17162021-02-18 02:17:37 +0000796 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800797 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
798 sLayerNameOne, sLayerNameOne,
799 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000800 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200801 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000802
803 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
804 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000805 presentFence1->signalForTest(65);
806 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000807
808 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +0000809 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Partial);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200810
811 auto jankData = getLayerOneJankData();
812 EXPECT_EQ(jankData.size(), 1u);
813 EXPECT_EQ(jankData[0].jankType, JankType::PredictionError);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000814}
815
816TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000817 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000818 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000819 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000820 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000821 JankType::BufferStuffing, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000822 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000823 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000824 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
825 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800826 FrameTimelineInfo ftInfo;
827 ftInfo.vsyncId = surfaceFrameToken1;
828 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000829
Adithya Srinivasanead17162021-02-18 02:17:37 +0000830 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800831 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
832 sLayerNameOne, sLayerNameOne,
833 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000834 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200835 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000836
837 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000838 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000839 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000840 presentFence1->signalForTest(90);
841 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000842
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000843 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +0000844 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200845
846 auto jankData = getLayerOneJankData();
847 EXPECT_EQ(jankData.size(), 1u);
848 EXPECT_EQ(jankData[0].jankType, JankType::BufferStuffing);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000849}
850
Alec Mouri363faf02021-01-29 16:34:55 -0800851TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200852 Fps refreshRate = RR_11;
853 Fps renderRate = RR_30;
Alec Mouri363faf02021-01-29 16:34:55 -0800854 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000855 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne,
856 sLayerNameOne, sGameMode,
857 JankType::AppDeadlineMissed, -4, 0,
858 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800859 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000860 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
861 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800862 FrameTimelineInfo ftInfo;
863 ftInfo.vsyncId = surfaceFrameToken1;
864 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000865
Alec Mouri363faf02021-01-29 16:34:55 -0800866 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800867 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
868 sLayerNameOne, sLayerNameOne,
869 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000870 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200871 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800872
873 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
874 surfaceFrame1->setRenderRate(renderRate);
875 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000876 presentFence1->signalForTest(90);
877 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800878
879 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000880 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200881
882 auto jankData = getLayerOneJankData();
883 EXPECT_EQ(jankData.size(), 1u);
884 EXPECT_EQ(jankData[0].jankType, JankType::AppDeadlineMissed);
Alec Mouri363faf02021-01-29 16:34:55 -0800885}
886
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000887TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200888 Fps refreshRate = RR_11;
889 Fps renderRate = RR_30;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000890
891 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000892 incrementJankyFrames(
893 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000894 sGameMode,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000895 JankType::Unknown | JankType::AppDeadlineMissed,
Adithya Srinivasande272452021-04-10 00:21:00 +0000896 0, 0, 25}));
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000897 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
898 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
899 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800900 FrameTimelineInfo ftInfo;
901 ftInfo.vsyncId = surfaceFrameToken1;
902 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000903
904 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800905 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
906 sLayerNameOne, sLayerNameOne,
907 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000908 surfaceFrame1->setAcquireFenceTime(45);
909 // Trigger a prediction expiry
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000910 flushTokens();
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200911 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000912
913 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
914 surfaceFrame1->setRenderRate(renderRate);
915 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
916 presentFence1->signalForTest(90);
917 mFrameTimeline->setSfPresent(86, presentFence1);
918
919 auto displayFrame = getDisplayFrame(0);
920 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +0000921 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000922 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
923 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
924 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
925
926 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000927 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000928 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Pascal Mütschardd56514e2024-05-24 17:37:13 +0200929
930 auto jankData = getLayerOneJankData();
931 EXPECT_EQ(jankData.size(), 1u);
932 EXPECT_EQ(jankData[0].jankType, JankType::Unknown | JankType::AppDeadlineMissed);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000933}
934
Adithya Srinivasan01189672020-10-20 14:23:05 -0700935/*
936 * Tracing Tests
937 *
938 * Trace packets are flushed all the way only when the next packet is traced.
939 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
940 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
941 * will have additional empty frames created for this reason.
942 */
943TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
944 auto tracingSession = getTracingSessionForTest();
945 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700946 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800947 FrameTimelineInfo ftInfo;
948 ftInfo.vsyncId = token1;
949 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000950 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800951 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
952 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000953 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700954
955 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200956 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800957 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
958 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700959 mFrameTimeline->setSfPresent(25, presentFence1);
960 presentFence1->signalForTest(30);
961
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000962 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700963
964 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000965 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700966}
967
968TEST_F(FrameTimelineTest, tracing_sanityTest) {
969 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800970 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800971 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700972 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700973
974 tracingSession->StartBlocking();
975 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
976 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800977 FrameTimelineInfo ftInfo;
978 ftInfo.vsyncId = token1;
979 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000980 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800981 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
982 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000983 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700984
985 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200986 mFrameTimeline->setSfWakeUp(token2, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800987 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
988 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700989 mFrameTimeline->setSfPresent(25, presentFence1);
990 presentFence1->signalForTest(30);
991
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000992 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000993 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700994 tracingSession->StopBlocking();
995
996 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000997 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000998 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700999}
1000
1001TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
1002 auto tracingSession = getTracingSessionForTest();
1003 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001004
1005 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001006
1007 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001008 mFrameTimeline->setSfWakeUp(-1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001009 mFrameTimeline->setSfPresent(25, presentFence1);
1010 presentFence1->signalForTest(30);
1011
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001012 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001013 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001014 tracingSession->StopBlocking();
1015
1016 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001017 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001018}
1019
1020TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
1021 auto tracingSession = getTracingSessionForTest();
1022 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001023
1024 tracingSession->StartBlocking();
1025 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -08001026 auto surfaceFrame1 =
1027 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001028 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001029 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001030
1031 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001032 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001033 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1034 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001035 mFrameTimeline->setSfPresent(25, presentFence1);
1036 presentFence1->signalForTest(30);
1037
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001038 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001039 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001040 tracingSession->StopBlocking();
1041
1042 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001043 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
1044 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001045 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001046}
1047
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001048ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
1049 pid_t pid) {
1050 ProtoExpectedDisplayFrameStart proto;
1051 proto.set_cookie(cookie);
1052 proto.set_token(token);
1053 proto.set_pid(pid);
1054 return proto;
1055}
1056
1057ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
1058 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Ying Wei96eb5352023-11-21 17:37:21 +00001059 bool gpuComposition, ProtoJankType jankType, ProtoJankSeverityType jankSeverityType,
1060 ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001061 ProtoActualDisplayFrameStart proto;
1062 proto.set_cookie(cookie);
1063 proto.set_token(token);
1064 proto.set_pid(pid);
1065 proto.set_present_type(presentType);
1066 proto.set_on_time_finish(onTimeFinish);
1067 proto.set_gpu_composition(gpuComposition);
1068 proto.set_jank_type(jankType);
Ying Wei96eb5352023-11-21 17:37:21 +00001069 proto.set_jank_severity_type(jankSeverityType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001070 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001071 return proto;
1072}
1073
1074ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
1075 int64_t displayFrameToken,
1076 pid_t pid,
1077 std::string layerName) {
1078 ProtoExpectedSurfaceFrameStart proto;
1079 proto.set_cookie(cookie);
1080 proto.set_token(token);
1081 proto.set_display_frame_token(displayFrameToken);
1082 proto.set_pid(pid);
1083 proto.set_layer_name(layerName);
1084 return proto;
1085}
1086
1087ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
1088 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
1089 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Ying Wei96eb5352023-11-21 17:37:21 +00001090 ProtoJankType jankType, ProtoJankSeverityType jankSeverityType,
1091 ProtoPredictionType predictionType, bool isBuffer) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001092 ProtoActualSurfaceFrameStart proto;
1093 proto.set_cookie(cookie);
1094 proto.set_token(token);
1095 proto.set_display_frame_token(displayFrameToken);
1096 proto.set_pid(pid);
1097 proto.set_layer_name(layerName);
1098 proto.set_present_type(presentType);
1099 proto.set_on_time_finish(onTimeFinish);
1100 proto.set_gpu_composition(gpuComposition);
1101 proto.set_jank_type(jankType);
Ying Wei96eb5352023-11-21 17:37:21 +00001102 proto.set_jank_severity_type(jankSeverityType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001103 proto.set_prediction_type(predictionType);
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001104 proto.set_is_buffer(isBuffer);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001105 return proto;
1106}
1107
1108ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
1109 ProtoFrameEnd proto;
1110 proto.set_cookie(cookie);
1111 return proto;
1112}
1113
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001114void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
1115 const ProtoExpectedDisplayFrameStart& source) {
1116 ASSERT_TRUE(received.has_cookie());
1117 EXPECT_EQ(received.cookie(), source.cookie());
1118
Adithya Srinivasan01189672020-10-20 14:23:05 -07001119 ASSERT_TRUE(received.has_token());
1120 EXPECT_EQ(received.token(), source.token());
1121
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001122 ASSERT_TRUE(received.has_pid());
1123 EXPECT_EQ(received.pid(), source.pid());
1124}
1125
1126void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
1127 const ProtoActualDisplayFrameStart& source) {
1128 ASSERT_TRUE(received.has_cookie());
1129 EXPECT_EQ(received.cookie(), source.cookie());
1130
1131 ASSERT_TRUE(received.has_token());
1132 EXPECT_EQ(received.token(), source.token());
1133
1134 ASSERT_TRUE(received.has_pid());
1135 EXPECT_EQ(received.pid(), source.pid());
1136
Adithya Srinivasan01189672020-10-20 14:23:05 -07001137 ASSERT_TRUE(received.has_present_type());
1138 EXPECT_EQ(received.present_type(), source.present_type());
1139 ASSERT_TRUE(received.has_on_time_finish());
1140 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1141 ASSERT_TRUE(received.has_gpu_composition());
1142 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1143 ASSERT_TRUE(received.has_jank_type());
1144 EXPECT_EQ(received.jank_type(), source.jank_type());
Ying Wei96eb5352023-11-21 17:37:21 +00001145 ASSERT_TRUE(received.has_jank_severity_type());
1146 EXPECT_EQ(received.jank_severity_type(), source.jank_severity_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001147 ASSERT_TRUE(received.has_prediction_type());
1148 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001149}
1150
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001151void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
1152 const ProtoExpectedSurfaceFrameStart& source) {
1153 ASSERT_TRUE(received.has_cookie());
1154 EXPECT_EQ(received.cookie(), source.cookie());
1155
Adithya Srinivasan01189672020-10-20 14:23:05 -07001156 ASSERT_TRUE(received.has_token());
1157 EXPECT_EQ(received.token(), source.token());
1158
1159 ASSERT_TRUE(received.has_display_frame_token());
1160 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1161
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001162 ASSERT_TRUE(received.has_pid());
1163 EXPECT_EQ(received.pid(), source.pid());
1164
1165 ASSERT_TRUE(received.has_layer_name());
1166 EXPECT_EQ(received.layer_name(), source.layer_name());
1167}
1168
1169void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
1170 const ProtoActualSurfaceFrameStart& source) {
1171 ASSERT_TRUE(received.has_cookie());
1172 EXPECT_EQ(received.cookie(), source.cookie());
1173
1174 ASSERT_TRUE(received.has_token());
1175 EXPECT_EQ(received.token(), source.token());
1176
1177 ASSERT_TRUE(received.has_display_frame_token());
1178 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1179
1180 ASSERT_TRUE(received.has_pid());
1181 EXPECT_EQ(received.pid(), source.pid());
1182
1183 ASSERT_TRUE(received.has_layer_name());
1184 EXPECT_EQ(received.layer_name(), source.layer_name());
1185
Adithya Srinivasan01189672020-10-20 14:23:05 -07001186 ASSERT_TRUE(received.has_present_type());
1187 EXPECT_EQ(received.present_type(), source.present_type());
1188 ASSERT_TRUE(received.has_on_time_finish());
1189 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1190 ASSERT_TRUE(received.has_gpu_composition());
1191 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1192 ASSERT_TRUE(received.has_jank_type());
1193 EXPECT_EQ(received.jank_type(), source.jank_type());
Ying Wei96eb5352023-11-21 17:37:21 +00001194 ASSERT_TRUE(received.has_jank_severity_type());
1195 EXPECT_EQ(received.jank_severity_type(), source.jank_severity_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001196 ASSERT_TRUE(received.has_prediction_type());
1197 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001198 ASSERT_TRUE(received.has_is_buffer());
1199 EXPECT_EQ(received.is_buffer(), source.is_buffer());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001200}
Adithya Srinivasan01189672020-10-20 14:23:05 -07001201
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001202void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
1203 ASSERT_TRUE(received.has_cookie());
1204 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001205}
1206
Sally Qi2269a692024-05-17 18:02:28 -07001207TEST_F(FrameTimelineTest, traceDisplayFrameNoSkipped) {
1208 // setup 2 display frames
1209 // DF 1: [22, 30] -> [0, 11]
1210 // DF 2: [82, 90] -> SF [5, 16]
1211 auto tracingSession = getTracingSessionForTest();
1212 tracingSession->StartBlocking();
1213 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1214 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 100});
1215 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({0, 11, 25});
1216 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1217 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1218
1219 int64_t traceCookie = snoopCurrentTraceCookie();
1220
1221 // set up 1st display frame
1222 FrameTimelineInfo ftInfo1;
1223 ftInfo1.vsyncId = surfaceFrameToken1;
1224 ftInfo1.inputEventId = sInputEventId;
1225 auto surfaceFrame1 =
1226 mFrameTimeline->createSurfaceFrameForToken(ftInfo1, sPidOne, sUidOne, sLayerIdOne,
1227 sLayerNameOne, sLayerNameOne,
1228 /*isBuffer*/ true, sGameMode);
1229 surfaceFrame1->setAcquireFenceTime(11);
1230 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_30);
1231 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1232 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1233 mFrameTimeline->setSfPresent(30, presentFence1);
1234 presentFence1->signalForTest(40);
1235
1236 // Trigger a flush by finalizing the next DisplayFrame
1237 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1238 FrameTimelineInfo ftInfo2;
1239 ftInfo2.vsyncId = surfaceFrameToken2;
1240 ftInfo2.inputEventId = sInputEventId;
1241 auto surfaceFrame2 =
1242 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1243 sLayerNameOne, sLayerNameOne,
1244 /*isBuffer*/ true, sGameMode);
1245
1246 // set up 2nd display frame
1247 surfaceFrame2->setAcquireFenceTime(16);
1248 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_11, RR_30);
1249 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1250 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1251 mFrameTimeline->setSfPresent(90, presentFence2);
1252 presentFence2->signalForTest(100);
1253
1254 // the token of skipped Display Frame
1255 auto protoSkippedActualDisplayFrameStart =
1256 createProtoActualDisplayFrameStart(traceCookie + 9, 0, kSurfaceFlingerPid,
1257 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1258 FrameTimelineEvent::JANK_DROPPED,
1259 FrameTimelineEvent::SEVERITY_NONE,
1260 FrameTimelineEvent::PREDICTION_VALID);
1261 auto protoSkippedActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 9);
1262
1263 // Trigger a flush by finalizing the next DisplayFrame
1264 addEmptyDisplayFrame();
1265 flushTrace();
1266 tracingSession->StopBlocking();
1267
1268 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1269 // 8 Valid Display Frames + 8 Valid Surface Frames + no Skipped Display Frames
1270 EXPECT_EQ(packets.size(), 16u);
1271}
1272
Sally Qiaa107742023-09-29 14:53:14 -07001273TEST_F(FrameTimelineTest, traceDisplayFrameSkipped) {
Sally Qif5721252023-11-17 11:14:53 -08001274 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::add_sf_skipped_frames_to_trace,
1275 true);
1276
Sally Qiaa107742023-09-29 14:53:14 -07001277 // setup 2 display frames
1278 // DF 1: [22,40] -> [5, 40]
1279 // DF : [36, 70] (Skipped one, added by the trace)
1280 // DF 2: [82, 100] -> SF [25, 70]
1281 auto tracingSession = getTracingSessionForTest();
1282 tracingSession->StartBlocking();
1283 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1284 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 100});
1285 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1286 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1287 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1288
1289 int64_t traceCookie = snoopCurrentTraceCookie();
1290
1291 // set up 1st display frame
1292 FrameTimelineInfo ftInfo1;
1293 ftInfo1.vsyncId = surfaceFrameToken1;
1294 ftInfo1.inputEventId = sInputEventId;
1295 auto surfaceFrame1 =
1296 mFrameTimeline->createSurfaceFrameForToken(ftInfo1, sPidOne, sUidOne, sLayerIdOne,
1297 sLayerNameOne, sLayerNameOne,
1298 /*isBuffer*/ true, sGameMode);
1299 surfaceFrame1->setAcquireFenceTime(16);
1300 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_30);
1301 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1302 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1303 mFrameTimeline->setSfPresent(30, presentFence1);
1304 presentFence1->signalForTest(40);
1305
1306 // Trigger a flush by finalizing the next DisplayFrame
1307 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1308 FrameTimelineInfo ftInfo2;
1309 ftInfo2.vsyncId = surfaceFrameToken2;
1310 ftInfo2.inputEventId = sInputEventId;
1311 auto surfaceFrame2 =
1312 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1313 sLayerNameOne, sLayerNameOne,
1314 /*isBuffer*/ true, sGameMode);
1315
1316 // set up 2nd display frame
1317 surfaceFrame2->setAcquireFenceTime(36);
1318 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_11, RR_30);
1319 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1320 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1321 mFrameTimeline->setSfPresent(90, presentFence2);
1322 presentFence2->signalForTest(100);
1323
1324 // the token of skipped Display Frame
1325 auto protoSkippedActualDisplayFrameStart =
1326 createProtoActualDisplayFrameStart(traceCookie + 9, 0, kSurfaceFlingerPid,
1327 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1328 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001329 FrameTimelineEvent::SEVERITY_NONE,
Sally Qiaa107742023-09-29 14:53:14 -07001330 FrameTimelineEvent::PREDICTION_VALID);
1331 auto protoSkippedActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 9);
1332
1333 // Trigger a flush by finalizing the next DisplayFrame
1334 addEmptyDisplayFrame();
1335 flushTrace();
1336 tracingSession->StopBlocking();
1337
1338 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1339 // 8 Valid Display Frames + 8 Valid Surface Frames + 2 Skipped Display Frames
1340 EXPECT_EQ(packets.size(), 18u);
1341
1342 // Packet - 16: Actual skipped Display Frame Start
1343 // the timestamp should be equal to the 2nd expected surface frame's end time
1344 const auto& packet16 = packets[16];
1345 ASSERT_TRUE(packet16.has_timestamp());
1346 EXPECT_EQ(packet16.timestamp(), 36u);
1347 ASSERT_TRUE(packet16.has_frame_timeline_event());
1348
1349 const auto& event16 = packet16.frame_timeline_event();
1350 const auto& actualSkippedDisplayFrameStart = event16.actual_display_frame_start();
1351 validateTraceEvent(actualSkippedDisplayFrameStart, protoSkippedActualDisplayFrameStart);
1352
1353 // Packet - 17: Actual skipped Display Frame End
1354 // the timestamp should be equal to the 2nd expected surface frame's present time
1355 const auto& packet17 = packets[17];
1356 ASSERT_TRUE(packet17.has_timestamp());
1357 EXPECT_EQ(packet17.timestamp(), 70u);
1358 ASSERT_TRUE(packet17.has_frame_timeline_event());
1359
1360 const auto& event17 = packet17.frame_timeline_event();
1361 const auto& actualSkippedDisplayFrameEnd = event17.frame_end();
1362 validateTraceEvent(actualSkippedDisplayFrameEnd, protoSkippedActualDisplayFrameEnd);
1363}
1364
Adithya Srinivasan01189672020-10-20 14:23:05 -07001365TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
1366 auto tracingSession = getTracingSessionForTest();
1367 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001368
1369 tracingSession->StartBlocking();
Ady Abraham57a8ab42023-01-26 15:28:19 -08001370
1371 // Add an empty surface frame so that display frame would get traced.
1372 addEmptySurfaceFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001373 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001374
1375 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001376 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001377 mFrameTimeline->setSfPresent(26, presentFence1);
1378 presentFence1->signalForTest(31);
1379
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001380 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001381 auto protoExpectedDisplayFrameStart =
1382 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1383 kSurfaceFlingerPid);
1384 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1385 auto protoActualDisplayFrameStart =
1386 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
1387 kSurfaceFlingerPid,
1388 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001389 FrameTimelineEvent::JANK_NONE,
Ying Wei96eb5352023-11-21 17:37:21 +00001390 FrameTimelineEvent::SEVERITY_NONE,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001391 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001392 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001393
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001394 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001395 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001396 tracingSession->StopBlocking();
1397
1398 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001399 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001400
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001401 // Packet - 0 : ExpectedDisplayFrameStart
1402 const auto& packet0 = packets[0];
1403 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001404 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001405 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001406
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001407 const auto& event0 = packet0.frame_timeline_event();
1408 ASSERT_TRUE(event0.has_expected_display_frame_start());
1409 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
1410 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
1411
1412 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
1413 const auto& packet1 = packets[1];
1414 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001415 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001416 ASSERT_TRUE(packet1.has_frame_timeline_event());
1417
1418 const auto& event1 = packet1.frame_timeline_event();
1419 ASSERT_TRUE(event1.has_frame_end());
1420 const auto& expectedDisplayFrameEnd = event1.frame_end();
1421 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
1422
1423 // Packet - 2 : ActualDisplayFrameStart
1424 const auto& packet2 = packets[2];
1425 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001426 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001427 ASSERT_TRUE(packet2.has_frame_timeline_event());
1428
1429 const auto& event2 = packet2.frame_timeline_event();
1430 ASSERT_TRUE(event2.has_actual_display_frame_start());
1431 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1432 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1433
1434 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1435 const auto& packet3 = packets[3];
1436 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001437 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001438 ASSERT_TRUE(packet3.has_frame_timeline_event());
1439
1440 const auto& event3 = packet3.frame_timeline_event();
1441 ASSERT_TRUE(event3.has_frame_end());
1442 const auto& actualDisplayFrameEnd = event3.frame_end();
1443 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001444}
1445
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001446TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1447 auto tracingSession = getTracingSessionForTest();
1448 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1449
1450 tracingSession->StartBlocking();
1451 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1452 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001453 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001454
Ady Abraham57a8ab42023-01-26 15:28:19 -08001455 // Add an empty surface frame so that display frame would get traced.
1456 addEmptySurfaceFrame();
1457
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001458 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001459 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001460 mFrameTimeline->setSfPresent(26, presentFence1);
1461 presentFence1->signalForTest(31);
1462
1463 int64_t traceCookie = snoopCurrentTraceCookie();
1464
1465 auto protoActualDisplayFrameStart =
1466 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1467 kSurfaceFlingerPid,
1468 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001469 false, FrameTimelineEvent::JANK_UNKNOWN,
Ying Wei96eb5352023-11-21 17:37:21 +00001470 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001471 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001472 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1473
1474 addEmptyDisplayFrame();
1475 flushTrace();
1476 tracingSession->StopBlocking();
1477
1478 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1479 // Only actual timeline packets should be in the trace
1480 EXPECT_EQ(packets.size(), 2u);
1481
1482 // Packet - 0 : ActualDisplayFrameStart
1483 const auto& packet0 = packets[0];
1484 ASSERT_TRUE(packet0.has_timestamp());
1485 EXPECT_EQ(packet0.timestamp(), 20u);
1486 ASSERT_TRUE(packet0.has_frame_timeline_event());
1487
1488 const auto& event0 = packet0.frame_timeline_event();
1489 ASSERT_TRUE(event0.has_actual_display_frame_start());
1490 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1491 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1492
1493 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1494 const auto& packet1 = packets[1];
1495 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001496 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001497 ASSERT_TRUE(packet1.has_frame_timeline_event());
1498
1499 const auto& event1 = packet1.frame_timeline_event();
1500 ASSERT_TRUE(event1.has_frame_end());
1501 const auto& actualDisplayFrameEnd = event1.frame_end();
1502 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1503}
1504
Adithya Srinivasan01189672020-10-20 14:23:05 -07001505TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1506 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001507 // Layer specific increment
Edgar Arriaga631e4252023-03-02 02:11:24 +00001508 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001509 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1510 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1511
1512 tracingSession->StartBlocking();
1513 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1514 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001515
Huihong Luo3bdef862022-03-03 11:57:19 -08001516 FrameTimelineInfo ftInfo;
1517 ftInfo.vsyncId = surfaceFrameToken;
1518 ftInfo.inputEventId = sInputEventId;
1519
Adithya Srinivasan01189672020-10-20 14:23:05 -07001520 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001521 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1522 sLayerNameOne, sLayerNameOne,
1523 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001524 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001525 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1526 sLayerNameOne, sLayerNameOne,
1527 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001528 surfaceFrame1->setActualQueueTime(10);
1529 surfaceFrame1->setDropTime(15);
1530
1531 surfaceFrame2->setActualQueueTime(15);
1532 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001533
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001534 // First 2 cookies will be used by the DisplayFrame
1535 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1536
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001537 auto protoDroppedSurfaceFrameExpectedStart =
1538 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1539 displayFrameToken1, sPidOne, sLayerNameOne);
1540 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1541 auto protoDroppedSurfaceFrameActualStart =
1542 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1543 displayFrameToken1, sPidOne, sLayerNameOne,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001544 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1545 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001546 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001547 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001548 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001549
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001550 auto protoPresentedSurfaceFrameExpectedStart =
1551 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1552 displayFrameToken1, sPidOne, sLayerNameOne);
1553 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1554 auto protoPresentedSurfaceFrameActualStart =
1555 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1556 displayFrameToken1, sPidOne, sLayerNameOne,
1557 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001558 FrameTimelineEvent::JANK_NONE,
Ying Wei96eb5352023-11-21 17:37:21 +00001559 FrameTimelineEvent::SEVERITY_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001560 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001561 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001562
1563 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001564 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001565 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1566 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001567 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001568 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001569 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001570 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001571
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001572 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001573 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001574 tracingSession->StopBlocking();
1575
1576 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001577 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1578 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001579
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001580 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001581 const auto& packet4 = packets[4];
1582 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001583 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001584 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001585
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001586 const auto& event4 = packet4.frame_timeline_event();
1587 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001588 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1589 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001590
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001591 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001592 const auto& packet5 = packets[5];
1593 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001594 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001595 ASSERT_TRUE(packet5.has_frame_timeline_event());
1596
1597 const auto& event5 = packet5.frame_timeline_event();
1598 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001599 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1600 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001601
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001602 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001603 const auto& packet6 = packets[6];
1604 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001605 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001606 ASSERT_TRUE(packet6.has_frame_timeline_event());
1607
1608 const auto& event6 = packet6.frame_timeline_event();
1609 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001610 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1611 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001612
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001613 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001614 const auto& packet7 = packets[7];
1615 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001616 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001617 ASSERT_TRUE(packet7.has_frame_timeline_event());
1618
1619 const auto& event7 = packet7.frame_timeline_event();
1620 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001621 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1622 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1623
1624 // Packet - 8 : ExpectedSurfaceFrameStart2
1625 const auto& packet8 = packets[8];
1626 ASSERT_TRUE(packet8.has_timestamp());
1627 EXPECT_EQ(packet8.timestamp(), 10u);
1628 ASSERT_TRUE(packet8.has_frame_timeline_event());
1629
1630 const auto& event8 = packet8.frame_timeline_event();
1631 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1632 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1633 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1634
1635 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1636 const auto& packet9 = packets[9];
1637 ASSERT_TRUE(packet9.has_timestamp());
1638 EXPECT_EQ(packet9.timestamp(), 25u);
1639 ASSERT_TRUE(packet9.has_frame_timeline_event());
1640
1641 const auto& event9 = packet9.frame_timeline_event();
1642 ASSERT_TRUE(event9.has_frame_end());
1643 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1644 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1645
1646 // Packet - 10 : ActualSurfaceFrameStart2
1647 const auto& packet10 = packets[10];
1648 ASSERT_TRUE(packet10.has_timestamp());
1649 EXPECT_EQ(packet10.timestamp(), 10u);
1650 ASSERT_TRUE(packet10.has_frame_timeline_event());
1651
1652 const auto& event10 = packet10.frame_timeline_event();
1653 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1654 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1655 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1656
1657 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1658 const auto& packet11 = packets[11];
1659 ASSERT_TRUE(packet11.has_timestamp());
1660 EXPECT_EQ(packet11.timestamp(), 20u);
1661 ASSERT_TRUE(packet11.has_frame_timeline_event());
1662
1663 const auto& event11 = packet11.frame_timeline_event();
1664 ASSERT_TRUE(event11.has_frame_end());
1665 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1666 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1667}
1668
Ady Abrahame43ff722022-02-15 14:44:25 -08001669TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredIsAppMissedDeadline) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001670 auto tracingSession = getTracingSessionForTest();
1671 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1672
1673 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001674 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1675 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1676 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001677 int64_t surfaceFrameToken =
1678 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1679
1680 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001681 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001682 FrameTimelineInfo ftInfo;
1683 ftInfo.vsyncId = surfaceFrameToken;
1684 ftInfo.inputEventId = 0;
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001685 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001686 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1687 sLayerNameOne, sLayerNameOne,
1688 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001689 surfaceFrame1->setActualQueueTime(appEndTime);
1690 surfaceFrame1->setAcquireFenceTime(appEndTime);
1691
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001692 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1693 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1694 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001695 int64_t displayFrameToken =
1696 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1697
1698 // First 2 cookies will be used by the DisplayFrame
1699 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1700
1701 auto protoActualSurfaceFrameStart =
1702 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1703 displayFrameToken, sPidOne, sLayerNameOne,
1704 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Ady Abrahame43ff722022-02-15 14:44:25 -08001705 false, FrameTimelineEvent::JANK_APP_DEADLINE_MISSED,
Ying Wei96eb5352023-11-21 17:37:21 +00001706 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001707 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001708 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1709
1710 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001711 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001712 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1713 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1714 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1715 presentFence1->signalForTest(sfPresentTime);
1716
1717 addEmptyDisplayFrame();
1718 flushTrace();
1719 tracingSession->StopBlocking();
1720
1721 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1722 // Display Frame 4 packets + SurfaceFrame 2 packets
1723 ASSERT_EQ(packets.size(), 6u);
1724
1725 // Packet - 4 : ActualSurfaceFrameStart
1726 const auto& packet4 = packets[4];
1727 ASSERT_TRUE(packet4.has_timestamp());
1728 EXPECT_EQ(packet4.timestamp(),
1729 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1730 ASSERT_TRUE(packet4.has_frame_timeline_event());
1731
1732 const auto& event4 = packet4.frame_timeline_event();
1733 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1734 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1735 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1736
1737 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1738 const auto& packet5 = packets[5];
1739 ASSERT_TRUE(packet5.has_timestamp());
1740 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1741 ASSERT_TRUE(packet5.has_frame_timeline_event());
1742
1743 const auto& event5 = packet5.frame_timeline_event();
1744 ASSERT_TRUE(event5.has_frame_end());
1745 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001746 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001747}
1748
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001749TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDroppedFramesTracedProperly) {
1750 auto tracingSession = getTracingSessionForTest();
1751 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1752
1753 tracingSession->StartBlocking();
1754 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1755 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1756 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
1757 int64_t surfaceFrameToken =
1758 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1759
1760 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001761 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001762 FrameTimelineInfo ftInfo;
1763 ftInfo.vsyncId = surfaceFrameToken;
1764 ftInfo.inputEventId = 0;
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001765 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001766 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1767 sLayerNameOne, sLayerNameOne,
1768 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001769
1770 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(22ms).count();
1771 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1772 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
1773 int64_t displayFrameToken =
1774 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1775
1776 // First 2 cookies will be used by the DisplayFrame
1777 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1778
1779 auto protoActualSurfaceFrameStart =
1780 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1781 displayFrameToken, sPidOne, sLayerNameOne,
1782 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001783 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001784 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001785 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001786 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1787
1788 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001789 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001790 surfaceFrame1->setDropTime(sfStartTime);
1791 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1792 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1793 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1794 presentFence1->signalForTest(sfPresentTime);
1795
1796 addEmptyDisplayFrame();
1797 flushTrace();
1798 tracingSession->StopBlocking();
1799
1800 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1801 // Display Frame 4 packets + SurfaceFrame 2 packets
1802 ASSERT_EQ(packets.size(), 6u);
1803
1804 // Packet - 4 : ActualSurfaceFrameStart
1805 const auto& packet4 = packets[4];
1806 ASSERT_TRUE(packet4.has_timestamp());
1807 EXPECT_EQ(packet4.timestamp(),
1808 static_cast<uint64_t>(sfStartTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1809 ASSERT_TRUE(packet4.has_frame_timeline_event());
1810
1811 const auto& event4 = packet4.frame_timeline_event();
1812 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1813 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1814 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1815
1816 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1817 const auto& packet5 = packets[5];
1818 ASSERT_TRUE(packet5.has_timestamp());
1819 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(sfStartTime));
1820 ASSERT_TRUE(packet5.has_frame_timeline_event());
1821
1822 const auto& event5 = packet5.frame_timeline_event();
1823 ASSERT_TRUE(event5.has_frame_end());
1824 const auto& actualSurfaceFrameEnd = event5.frame_end();
1825 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
1826}
1827
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001828// Tests for Jank classification
1829TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001830 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001831 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001832 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1833 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001834 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -08001835 FrameTimelineInfo ftInfo;
1836 ftInfo.vsyncId = surfaceFrameToken;
1837 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001838 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -08001839 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1840 sLayerNameOne, sLayerNameOne,
1841 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001842 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001843 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1844 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1845 mFrameTimeline->setSfPresent(26, presentFence1);
1846 auto displayFrame = getDisplayFrame(0);
1847 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1848 presentFence1->signalForTest(29);
1849
1850 // Fences haven't been flushed yet, so it should be 0
1851 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1852 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1853
1854 addEmptyDisplayFrame();
1855 displayFrame = getDisplayFrame(0);
1856
1857 // Fences have flushed, so the present timestamps should be updated
1858 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1859 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1860 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1861 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1862 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00001863 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::None);
Pascal Mütschardd56514e2024-05-24 17:37:13 +02001864
1865 auto jankData = getLayerOneJankData();
1866 EXPECT_EQ(jankData.size(), 1u);
1867 EXPECT_EQ(jankData[0].jankType, JankType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001868}
1869
1870TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001871 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001872 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001873 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1874 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001875 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001876 mFrameTimeline->setSfPresent(26, presentFence1);
1877 auto displayFrame = getDisplayFrame(0);
1878 presentFence1->signalForTest(30);
1879
1880 // Fences for the first frame haven't been flushed yet, so it should be 0
1881 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1882
1883 // Trigger a flush by finalizing the next DisplayFrame
1884 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001885 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001886 mFrameTimeline->setSfPresent(56, presentFence2);
1887 displayFrame = getDisplayFrame(0);
1888
1889 // Fences for the first frame have flushed, so the present timestamps should be updated
1890 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1891 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1892 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1893 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00001894 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001895
1896 // Fences for the second frame haven't been flushed yet, so it should be 0
1897 auto displayFrame2 = getDisplayFrame(1);
1898 presentFence2->signalForTest(65);
1899 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001900 addEmptyDisplayFrame();
1901 displayFrame2 = getDisplayFrame(1);
1902
1903 // Fences for the second frame have flushed, so the present timestamps should be updated
1904 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1905 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1906 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1907 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00001908 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001909}
1910
1911TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001912 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001913 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001914 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1915 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001916 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001917 mFrameTimeline->setSfPresent(26, presentFence1);
1918 auto displayFrame = getDisplayFrame(0);
1919 presentFence1->signalForTest(50);
1920
1921 // Fences for the first frame haven't been flushed yet, so it should be 0
1922 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1923
1924 // Trigger a flush by finalizing the next DisplayFrame
1925 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001926 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001927 mFrameTimeline->setSfPresent(56, presentFence2);
1928 displayFrame = getDisplayFrame(0);
1929
1930 // Fences for the first frame have flushed, so the present timestamps should be updated
1931 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1932 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1933 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1934 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00001935 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001936
1937 // Fences for the second frame haven't been flushed yet, so it should be 0
1938 auto displayFrame2 = getDisplayFrame(1);
1939 presentFence2->signalForTest(75);
1940 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1941
1942 addEmptyDisplayFrame();
1943 displayFrame2 = getDisplayFrame(1);
1944
1945 // Fences for the second frame have flushed, so the present timestamps should be updated
1946 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1947 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1948 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1949 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00001950 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001951}
1952
1953TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001954 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1955 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001956 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001957
1958 mFrameTimeline->setSfPresent(22, presentFence1);
1959 auto displayFrame = getDisplayFrame(0);
1960 presentFence1->signalForTest(28);
1961
1962 // Fences haven't been flushed yet, so it should be 0
1963 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1964
1965 addEmptyDisplayFrame();
1966 displayFrame = getDisplayFrame(0);
1967
1968 // Fences have flushed, so the present timestamps should be updated
1969 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1970 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1971 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1972 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00001973 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001974}
1975
1976TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001977 /*
1978 * Case 1 - cpu time > vsync period but combined time > deadline > deadline -> cpudeadlinemissed
1979 * Case 2 - cpu time < vsync period but combined time > deadline -> gpudeadlinemissed
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001980 * Case 3 - previous frame ran longer -> sf_stuffing
1981 * Case 4 - Long cpu under SF stuffing -> cpudeadlinemissed
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001982 */
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001983 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001984 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001985 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1986 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001987 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1988 auto gpuFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001989 auto gpuFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1990 auto gpuFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001991 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001992 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001993 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1994 int64_t sfToken4 = mTokenManager->generateTokenForPredictions({112, 120, 120});
1995
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001996 // case 1 - cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001997 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001998 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
1999 auto displayFrame0 = getDisplayFrame(0);
2000 gpuFence1->signalForTest(36);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002001 presentFence1->signalForTest(52);
2002
2003 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00002004 EXPECT_EQ(displayFrame0->getActuals().presentTime, 0);
2005
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002006 // case 2 - cpu time = 56 - 52 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002007 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00002008 mFrameTimeline->setSfPresent(56, presentFence2, gpuFence2);
2009 auto displayFrame1 = getDisplayFrame(1);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002010 gpuFence2->signalForTest(76);
2011 presentFence2->signalForTest(90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00002012
2013 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2014 // Fences have flushed for first displayFrame, so the present timestamps should be updated
2015 EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
2016 EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2017 EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Rachel Lee94917b32022-03-18 17:52:09 -07002018 EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002019 EXPECT_EQ(displayFrame0->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002020
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002021 // case 3 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002022 mFrameTimeline->setSfWakeUp(sfToken3, 106, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002023 mFrameTimeline->setSfPresent(112, presentFence3, gpuFence3);
2024 auto displayFrame2 = getDisplayFrame(2);
2025 gpuFence3->signalForTest(116);
2026 presentFence3->signalForTest(120);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002027
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002028 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00002029 // Fences have flushed for second displayFrame, so the present timestamps should be updated
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002030 EXPECT_EQ(displayFrame1->getActuals().presentTime, 90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00002031 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2032 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2033 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002034 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002035
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002036 // case 4 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002037 mFrameTimeline->setSfWakeUp(sfToken4, 120, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002038 mFrameTimeline->setSfPresent(140, presentFence4, gpuFence4);
2039 auto displayFrame3 = getDisplayFrame(3);
2040 gpuFence4->signalForTest(156);
2041 presentFence4->signalForTest(180);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002042
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002043 EXPECT_EQ(displayFrame3->getActuals().presentTime, 0);
2044 // Fences have flushed for third displayFrame, so the present timestamps should be updated
2045 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
2046 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2047 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2048 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00002049 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002050
2051 addEmptyDisplayFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002052
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00002053 // Fences have flushed for third displayFrame, so the present timestamps should be updated
2054 EXPECT_EQ(displayFrame3->getActuals().presentTime, 180);
2055 EXPECT_EQ(displayFrame3->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2056 EXPECT_EQ(displayFrame3->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2057 EXPECT_EQ(displayFrame3->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002058 EXPECT_EQ(displayFrame3->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002059}
2060
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002061TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08002062 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002063 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002064 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
2065 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002066 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
2067 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08002068 FrameTimelineInfo ftInfo;
2069 ftInfo.vsyncId = surfaceFrameToken1;
2070 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002071 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002072 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2073 sLayerNameOne, sLayerNameOne,
2074 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002075 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002076 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002077 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2078 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002079 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002080 auto displayFrame1 = getDisplayFrame(0);
2081 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2082 presentFence1->signalForTest(30);
2083
2084 // Fences for the first frame haven't been flushed yet, so it should be 0
2085 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2086 auto actuals1 = presentedSurfaceFrame1.getActuals();
2087 EXPECT_EQ(actuals1.presentTime, 0);
2088
2089 // Trigger a flush by finalizing the next DisplayFrame
2090 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002091 FrameTimelineInfo ftInfo2;
2092 ftInfo2.vsyncId = surfaceFrameToken2;
2093 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002094 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002095 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2096 sLayerNameOne, sLayerNameOne,
2097 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002098 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002099 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002100 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2101 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002102 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002103 auto displayFrame2 = getDisplayFrame(1);
2104 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2105
2106 // Fences for the first frame have flushed, so the present timestamps should be updated
2107 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
2108 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2109 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2110 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00002111 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002112
2113 actuals1 = presentedSurfaceFrame1.getActuals();
2114 EXPECT_EQ(actuals1.presentTime, 30);
2115 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2116 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2117 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00002118 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002119
2120 // Fences for the second frame haven't been flushed yet, so it should be 0
2121 presentFence2->signalForTest(65);
2122 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2123 auto actuals2 = presentedSurfaceFrame2.getActuals();
2124 EXPECT_EQ(actuals2.presentTime, 0);
2125
Alec Mouri363faf02021-01-29 16:34:55 -08002126 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
2127
2128 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002129 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
2130 sLayerNameOne, sGameMode,
2131 JankType::PredictionError, -3, 5,
2132 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08002133
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002134 addEmptyDisplayFrame();
2135
2136 // Fences for the second frame have flushed, so the present timestamps should be updated
2137 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
2138 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2139 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2140 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002141 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002142
2143 actuals2 = presentedSurfaceFrame2.getActuals();
2144 EXPECT_EQ(actuals2.presentTime, 65);
2145 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2146 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2147 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002148 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002149}
2150
2151TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08002152 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002153 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002154 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
2155 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002156 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
2157 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08002158 FrameTimelineInfo ftInfo;
2159 ftInfo.vsyncId = surfaceFrameToken1;
2160 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002161 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002162 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2163 sLayerNameOne, sLayerNameOne,
2164 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002165 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002166 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002167 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2168 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2169 mFrameTimeline->setSfPresent(26, presentFence1);
2170 auto displayFrame1 = getDisplayFrame(0);
2171 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2172 presentFence1->signalForTest(50);
2173
2174 // Fences for the first frame haven't been flushed yet, so it should be 0
2175 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2176 auto actuals1 = presentedSurfaceFrame1.getActuals();
2177 EXPECT_EQ(actuals1.presentTime, 0);
2178
2179 // Trigger a flush by finalizing the next DisplayFrame
2180 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002181 FrameTimelineInfo ftInfo2;
2182 ftInfo2.vsyncId = surfaceFrameToken2;
2183 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002184 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002185 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2186 sLayerNameOne, sLayerNameOne,
2187 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002188 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002189 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002190 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2191 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002192 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002193 auto displayFrame2 = getDisplayFrame(1);
2194 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2195
2196 // Fences for the first frame have flushed, so the present timestamps should be updated
2197 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
2198 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2199 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2200 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002201 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002202
2203 actuals1 = presentedSurfaceFrame1.getActuals();
2204 EXPECT_EQ(actuals1.presentTime, 50);
2205 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2206 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2207 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002208 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002209
2210 // Fences for the second frame haven't been flushed yet, so it should be 0
2211 presentFence2->signalForTest(86);
2212 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2213 auto actuals2 = presentedSurfaceFrame2.getActuals();
2214 EXPECT_EQ(actuals2.presentTime, 0);
2215
Alec Mouri363faf02021-01-29 16:34:55 -08002216 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
2217
2218 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002219 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
2220 sLayerNameOne, sGameMode,
2221 JankType::PredictionError, -3, 5,
2222 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08002223
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002224 addEmptyDisplayFrame();
2225
2226 // Fences for the second frame have flushed, so the present timestamps should be updated
2227 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
2228 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2229 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2230 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002231 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002232
2233 actuals2 = presentedSurfaceFrame2.getActuals();
2234 EXPECT_EQ(actuals2.presentTime, 86);
2235 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2236 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2237 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002238 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002239}
2240
2241TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08002242 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08002243
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002244 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002245 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002246 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -08002247 FrameTimelineInfo ftInfo;
2248 ftInfo.vsyncId = surfaceFrameToken1;
2249 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002250 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002251 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2252 sLayerNameOne, sLayerNameOne,
2253 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002254 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002255 mFrameTimeline->setSfWakeUp(sfToken1, 42, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002256 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2257 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2258 mFrameTimeline->setSfPresent(46, presentFence1);
2259 auto displayFrame1 = getDisplayFrame(0);
2260 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2261 presentFence1->signalForTest(50);
2262
2263 // Fences for the first frame haven't been flushed yet, so it should be 0
2264 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2265 auto actuals1 = presentedSurfaceFrame1.getActuals();
2266 EXPECT_EQ(actuals1.presentTime, 0);
2267
2268 addEmptyDisplayFrame();
2269
2270 // Fences for the first frame have flushed, so the present timestamps should be updated
2271 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
2272 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2273 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2274 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002275 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002276
2277 actuals1 = presentedSurfaceFrame1.getActuals();
2278 EXPECT_EQ(actuals1.presentTime, 50);
2279 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2280 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2281 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +00002282 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002283}
2284
2285TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002286 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as only
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002287 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002288 // jank to the SurfaceFrame along with AppDeadlineMissed.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002289
Alec Mouri363faf02021-01-29 16:34:55 -08002290 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002291 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002292 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
2293 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002294 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
2295 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
Huihong Luo3bdef862022-03-03 11:57:19 -08002296 FrameTimelineInfo ftInfo;
2297 ftInfo.vsyncId = surfaceFrameToken1;
2298 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002299 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002300 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2301 sLayerNameOne, sLayerNameOne,
2302 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002303 surfaceFrame1->setAcquireFenceTime(26);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002304 mFrameTimeline->setSfWakeUp(sfToken1, 32, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002305 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2306 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2307 mFrameTimeline->setSfPresent(36, presentFence1);
2308 auto displayFrame1 = getDisplayFrame(0);
2309 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2310 presentFence1->signalForTest(40);
2311
2312 // Fences for the first frame haven't been flushed yet, so it should be 0
2313 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2314 auto actuals1 = presentedSurfaceFrame1.getActuals();
2315 EXPECT_EQ(actuals1.presentTime, 0);
2316
2317 // Trigger a flush by finalizing the next DisplayFrame
2318 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002319 FrameTimelineInfo ftInfo2;
2320 ftInfo2.vsyncId = surfaceFrameToken2;
2321 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002322 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002323 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2324 sLayerNameOne, sLayerNameOne,
2325 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002326 surfaceFrame2->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002327 mFrameTimeline->setSfWakeUp(sfToken2, 43, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002328 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2329 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2330 mFrameTimeline->setSfPresent(56, presentFence2);
2331 auto displayFrame2 = getDisplayFrame(1);
2332 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2333
2334 // Fences for the first frame have flushed, so the present timestamps should be updated
2335 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
2336 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2337 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2338 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002339 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002340
2341 actuals1 = presentedSurfaceFrame1.getActuals();
2342 EXPECT_EQ(actuals1.presentTime, 40);
2343 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2344 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2345 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002346 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002347
2348 // Fences for the second frame haven't been flushed yet, so it should be 0
2349 presentFence2->signalForTest(60);
2350 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2351 auto actuals2 = presentedSurfaceFrame2.getActuals();
2352 EXPECT_EQ(actuals2.presentTime, 0);
2353
2354 addEmptyDisplayFrame();
2355
2356 // Fences for the second frame have flushed, so the present timestamps should be updated
2357 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
2358 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2359 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2360 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002361 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002362
2363 actuals2 = presentedSurfaceFrame2.getActuals();
2364 EXPECT_EQ(actuals2.presentTime, 60);
2365 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2366 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002367 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2368 JankType::SurfaceFlingerCpuDeadlineMissed | JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002369 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002370}
2371
2372TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002373 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08002374 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002375 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2376 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2377 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2378
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002379 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2380 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Huihong Luo3bdef862022-03-03 11:57:19 -08002381 FrameTimelineInfo ftInfo;
2382 ftInfo.vsyncId = surfaceFrameToken1;
2383 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002384 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002385 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2386 sLayerNameOne, sLayerNameOne,
2387 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002388 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002389 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002390 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2391 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2392 mFrameTimeline->setSfPresent(56, presentFence1);
2393 auto displayFrame1 = getDisplayFrame(0);
2394 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2395 presentFence1->signalForTest(60);
2396
2397 // Fences for the first frame haven't been flushed yet, so it should be 0
2398 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2399 auto actuals1 = presentedSurfaceFrame1.getActuals();
2400 EXPECT_EQ(actuals1.presentTime, 0);
2401
2402 // Trigger a flush by finalizing the next DisplayFrame
2403 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002404 FrameTimelineInfo ftInfo2;
2405 ftInfo2.vsyncId = surfaceFrameToken2;
2406 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002407 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002408 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2409 sLayerNameOne, sLayerNameOne,
2410 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002411 surfaceFrame2->setAcquireFenceTime(84);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002412 mFrameTimeline->setSfWakeUp(sfToken2, 112, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002413 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2414 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2415 mFrameTimeline->setSfPresent(116, presentFence2);
2416 auto displayFrame2 = getDisplayFrame(1);
2417 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2418 presentFence2->signalForTest(120);
2419
2420 // Fences for the first frame have flushed, so the present timestamps should be updated
2421 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2422 actuals1 = presentedSurfaceFrame1.getActuals();
2423 EXPECT_EQ(actuals1.endTime, 50);
2424 EXPECT_EQ(actuals1.presentTime, 60);
2425
2426 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2427 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2428 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002429 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002430
2431 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2432 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2433 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002434 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002435
2436 // Fences for the second frame haven't been flushed yet, so it should be 0
2437 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2438 auto actuals2 = presentedSurfaceFrame2.getActuals();
2439 EXPECT_EQ(actuals2.presentTime, 0);
2440
2441 addEmptyDisplayFrame();
2442
2443 // Fences for the second frame have flushed, so the present timestamps should be updated
2444 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
2445 actuals2 = presentedSurfaceFrame2.getActuals();
2446 EXPECT_EQ(actuals2.presentTime, 120);
2447
2448 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2449 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2450 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002451 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002452
2453 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2454 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2455 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2456 JankType::AppDeadlineMissed | JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00002457 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002458}
Alec Mouriadebf5c2021-01-05 12:57:36 -08002459
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002460TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
2461 // Layer specific increment
2462 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
2463 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2464 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2465 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2466
2467 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2468 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -08002469 FrameTimelineInfo ftInfo;
2470 ftInfo.vsyncId = surfaceFrameToken1;
2471 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002472 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002473 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2474 sLayerNameOne, sLayerNameOne,
2475 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002476 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002477 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002478 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2479 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2480 mFrameTimeline->setSfPresent(56, presentFence1);
2481 auto displayFrame1 = getDisplayFrame(0);
2482 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2483 presentFence1->signalForTest(60);
2484
2485 // Fences for the first frame haven't been flushed yet, so it should be 0
2486 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2487 auto actuals1 = presentedSurfaceFrame1.getActuals();
2488 EXPECT_EQ(actuals1.presentTime, 0);
2489
2490 // Trigger a flush by finalizing the next DisplayFrame
2491 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002492 FrameTimelineInfo ftInfo2;
2493 ftInfo2.vsyncId = surfaceFrameToken2;
2494 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002495 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002496 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2497 sLayerNameOne, sLayerNameOne,
2498 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002499 surfaceFrame2->setAcquireFenceTime(80);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002500 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002501 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
2502 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2503 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2504 mFrameTimeline->setSfPresent(86, presentFence2);
2505 auto displayFrame2 = getDisplayFrame(1);
2506 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2507 presentFence2->signalForTest(90);
2508
2509 // Fences for the first frame have flushed, so the present timestamps should be updated
2510 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2511 actuals1 = presentedSurfaceFrame1.getActuals();
2512 EXPECT_EQ(actuals1.endTime, 50);
2513 EXPECT_EQ(actuals1.presentTime, 60);
2514
2515 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2516 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2517 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002518 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002519
2520 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2521 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2522 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002523 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002524
2525 // Fences for the second frame haven't been flushed yet, so it should be 0
2526 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2527 auto actuals2 = presentedSurfaceFrame2.getActuals();
2528 EXPECT_EQ(actuals2.presentTime, 0);
2529
2530 addEmptyDisplayFrame();
2531
2532 // Fences for the second frame have flushed, so the present timestamps should be updated
2533 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2534 actuals2 = presentedSurfaceFrame2.getActuals();
2535 EXPECT_EQ(actuals2.presentTime, 90);
2536
2537 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2538 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2539 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002540 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002541
2542 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2543 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2544 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00002545 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002546}
2547
Rachel Lee94917b32022-03-18 17:52:09 -07002548TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent_GpuAndCpuMiss) {
2549 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2550 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2551 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2552 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2553 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2554
2555 // Case 1: cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002556 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Rachel Lee94917b32022-03-18 17:52:09 -07002557 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
2558 auto displayFrame = getDisplayFrame(0);
2559 gpuFence1->signalForTest(36);
2560 presentFence1->signalForTest(52);
2561
2562 // Fences haven't been flushed yet, so it should be 0
2563 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
2564
2565 addEmptyDisplayFrame();
2566 displayFrame = getDisplayFrame(0);
2567
2568 // Fences have flushed, so the present timestamps should be updated
2569 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
2570 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2571 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2572 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002573 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Full);
Rachel Lee94917b32022-03-18 17:52:09 -07002574
2575 // Case 2: No GPU fence so it will not use GPU composition.
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002576 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Rachel Lee94917b32022-03-18 17:52:09 -07002577 mFrameTimeline->setSfPresent(66, presentFence2);
2578 auto displayFrame2 = getDisplayFrame(2); // 2 because of previous empty frame
2579 presentFence2->signalForTest(90);
2580
2581 // Fences for the frame haven't been flushed yet, so it should be 0
2582 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2583
2584 addEmptyDisplayFrame();
2585
2586 // Fences have flushed, so the present timestamps should be updated
2587 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2588 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2589 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2590 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002591 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Rachel Lee94917b32022-03-18 17:52:09 -07002592}
2593
Ady Abrahamfcb16862022-10-10 14:35:21 -07002594TEST_F(FrameTimelineTest, jankClassification_presentFenceError) {
2595 auto erroneousPresentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2596 auto erroneousPresentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2597 auto validPresentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2598 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2599 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2600 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({72, 80, 80});
2601
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002602 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002603 mFrameTimeline->setSfPresent(26, erroneousPresentFence1);
2604
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002605 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002606 mFrameTimeline->setSfPresent(60, erroneousPresentFence2);
2607
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002608 mFrameTimeline->setSfWakeUp(sfToken3, 72, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002609 mFrameTimeline->setSfPresent(80, validPresentFence);
2610
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002611 erroneousPresentFence2->signalForTest(2);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002612 validPresentFence->signalForTest(80);
2613
2614 addEmptyDisplayFrame();
2615
2616 {
2617 auto displayFrame = getDisplayFrame(0);
2618 EXPECT_EQ(displayFrame->getActuals().presentTime, 26);
2619 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2620 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002621 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002622 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002623 }
2624 {
2625 auto displayFrame = getDisplayFrame(1);
2626 EXPECT_EQ(displayFrame->getActuals().presentTime, 60);
2627 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2628 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002629 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002630 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002631 }
2632 {
2633 auto displayFrame = getDisplayFrame(2);
2634 EXPECT_EQ(displayFrame->getActuals().presentTime, 80);
2635 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2636 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2637 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002638 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::None);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002639 }
2640}
2641
Alec Mouriadebf5c2021-01-05 12:57:36 -08002642TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
2643 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
2644}
2645
2646TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002647 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002648
2649 auto surfaceFrame1 =
2650 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002651 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002652 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002653 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2654 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2655 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2656 presentFence1->signalForTest(oneHundredMs);
2657 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2658
2659 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2660}
2661
2662TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002663 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2664 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002665 auto surfaceFrame1 =
2666 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002667 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002668 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002669 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2670 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2671 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2672 presentFence1->signalForTest(oneHundredMs);
2673 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2674
2675 auto surfaceFrame2 =
2676 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002677 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002678 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002679 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2680 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2681 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2682 presentFence2->signalForTest(twoHundredMs);
2683 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2684
2685 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
2686}
2687
2688TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002689 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2690 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002691 auto surfaceFrame1 =
2692 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002693 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002694 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002695 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2696 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2697 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2698 presentFence1->signalForTest(oneHundredMs);
2699 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2700
2701 auto surfaceFrame2 =
2702 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002703 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002704 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002705 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2706 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2707 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2708 presentFence2->signalForTest(twoHundredMs);
2709 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2710
2711 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
2712}
2713
2714TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002715 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2716 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002717 auto surfaceFrame1 =
2718 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002719 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002720 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002721 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2722 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2723 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2724 presentFence1->signalForTest(oneHundredMs);
2725 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2726
2727 auto surfaceFrame2 =
2728 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002729 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002730 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002731 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2732 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2733 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2734 presentFence2->signalForTest(twoHundredMs);
2735 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2736
2737 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2738}
2739
2740TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002741 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2742 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2743 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2744 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2745 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002746 auto surfaceFrame1 =
2747 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002748 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002749 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002750 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2751 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2752 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2753 presentFence1->signalForTest(oneHundredMs);
2754 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2755
2756 auto surfaceFrame2 =
2757 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002758 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002759 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002760 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2761 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2762 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2763 presentFence2->signalForTest(twoHundredMs);
2764 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2765
2766 auto surfaceFrame3 =
2767 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002768 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002769 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002770 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2771 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2772 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2773 presentFence3->signalForTest(threeHundredMs);
2774 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2775
2776 auto surfaceFrame4 =
2777 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002778 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002779 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002780 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2781 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2782 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2783 presentFence4->signalForTest(fiveHundredMs);
2784 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2785
2786 auto surfaceFrame5 =
2787 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002788 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002789 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002790 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2791 // Dropped frames will be excluded from fps computation
2792 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2793 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2794 presentFence5->signalForTest(sixHundredMs);
2795 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2796
2797 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2798}
2799
ramindaniea2bb822022-06-27 19:52:10 +00002800TEST_F(FrameTimelineTest, getMinTime) {
2801 // Use SurfaceFrame::getBaseTime to test the getMinTime.
2802 FrameTimelineInfo ftInfo;
2803
2804 // Valid prediction state test.
2805 ftInfo.vsyncId = 0L;
2806 mTokenManager->generateTokenForPredictions({10});
2807 auto surfaceFrame =
2808 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2809 sLayerNameOne, sLayerNameOne,
2810 /*isBuffer*/ true, sGameMode);
2811 ASSERT_EQ(surfaceFrame->getBaseTime(), 10);
2812
2813 // Test prediction state which is not valid.
2814 ftInfo.vsyncId = FrameTimelineInfo::INVALID_VSYNC_ID;
2815 surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2816 sLayerNameOne, sLayerNameOne,
2817 /*isBuffer*/ true, sGameMode);
2818 // Start time test.
2819 surfaceFrame->setActualStartTime(200);
2820 ASSERT_EQ(surfaceFrame->getBaseTime(), 200);
2821
2822 // End time test.
2823 surfaceFrame->setAcquireFenceTime(100);
2824 ASSERT_EQ(surfaceFrame->getBaseTime(), 100);
2825
2826 // Present time test.
2827 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2828 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2829 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2830 presentFence->signalForTest(std::chrono::nanoseconds(50ns).count());
2831 mFrameTimeline->setSfPresent(50, presentFence);
2832 ASSERT_EQ(surfaceFrame->getBaseTime(), 50);
2833}
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002834
2835TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingDisplayRate) {
2836 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2837 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2838 FrameTimelineInfo ftInfo;
2839 ftInfo.vsyncId = token1;
2840 ftInfo.inputEventId = sInputEventId;
2841 auto surfaceFrame =
2842 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2843 sLayerNameOne, sLayerNameOne,
2844 /*isBuffer*/ true, sGameMode);
2845
2846 mFrameTimeline->setSfWakeUp(token1, 20, RR_30, RR_11);
2847 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2848 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2849 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2850 mFrameTimeline->setSfPresent(50, presentFence1);
2851
2852 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 11);
2853}
2854
2855TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingAppFrameRate) {
2856 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2857 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2858 FrameTimelineInfo ftInfo;
2859 ftInfo.vsyncId = token1;
2860 ftInfo.inputEventId = sInputEventId;
2861 auto surfaceFrame =
2862 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2863 sLayerNameOne, sLayerNameOne,
2864 /*isBuffer*/ true, sGameMode);
2865 surfaceFrame->setRenderRate(RR_30);
2866 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
2867 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2868 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2869 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2870 mFrameTimeline->setSfPresent(50, presentFence1);
2871
2872 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 30);
2873}
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002874} // namespace android::frametimeline