blob: dac9265b71a2d13e47c06e469141bb5c48422f03 [file] [log] [blame]
Adithya Srinivasanf279e042020-08-17 14:56:27 -07001/*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Ady Abraham3db8a3c2023-11-20 17:53:47 -080017#include <common/test/FlagUtils.h>
Sally Qif5721252023-11-17 11:14:53 -080018#include "com_android_graphics_surfaceflinger_flags.h"
Alec Mouri9a29e672020-09-14 12:39:14 -070019#include "gmock/gmock-spec-builders.h"
20#include "mock/MockTimeStats.h"
Adithya Srinivasanf279e042020-08-17 14:56:27 -070021#undef LOG_TAG
22#define LOG_TAG "LibSurfaceFlingerUnittests"
23
24#include <FrameTimeline/FrameTimeline.h>
25#include <gtest/gtest.h>
26#include <log/log.h>
Adithya Srinivasan01189672020-10-20 14:23:05 -070027#include <perfetto/trace/trace.pb.h>
Adithya Srinivasanf279e042020-08-17 14:56:27 -070028#include <cinttypes>
29
30using namespace std::chrono_literals;
Alec Mouri363faf02021-01-29 16:34:55 -080031using testing::_;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -080032using testing::AtLeast;
Alec Mouri9a29e672020-09-14 12:39:14 -070033using testing::Contains;
Adithya Srinivasan01189672020-10-20 14:23:05 -070034using FrameTimelineEvent = perfetto::protos::FrameTimelineEvent;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000035using ProtoExpectedDisplayFrameStart =
36 perfetto::protos::FrameTimelineEvent_ExpectedDisplayFrameStart;
37using ProtoExpectedSurfaceFrameStart =
38 perfetto::protos::FrameTimelineEvent_ExpectedSurfaceFrameStart;
39using ProtoActualDisplayFrameStart = perfetto::protos::FrameTimelineEvent_ActualDisplayFrameStart;
40using ProtoActualSurfaceFrameStart = perfetto::protos::FrameTimelineEvent_ActualSurfaceFrameStart;
41using ProtoFrameEnd = perfetto::protos::FrameTimelineEvent_FrameEnd;
Adithya Srinivasan01189672020-10-20 14:23:05 -070042using ProtoPresentType = perfetto::protos::FrameTimelineEvent_PresentType;
43using ProtoJankType = perfetto::protos::FrameTimelineEvent_JankType;
Ying Wei96eb5352023-11-21 17:37:21 +000044using ProtoJankSeverityType = perfetto::protos::FrameTimelineEvent_JankSeverityType;
Adithya Srinivasan78e58af2021-02-25 00:08:08 +000045using ProtoPredictionType = perfetto::protos::FrameTimelineEvent_PredictionType;
Alec Mouri9a29e672020-09-14 12:39:14 -070046
Adithya Srinivasanf279e042020-08-17 14:56:27 -070047namespace android::frametimeline {
48
Ady Abraham57a8ab42023-01-26 15:28:19 -080049static const std::string sLayerNameOne = "layer1";
50static const std::string sLayerNameTwo = "layer2";
51
52constexpr const uid_t sUidOne = 0;
53constexpr pid_t sPidOne = 10;
54constexpr pid_t sPidTwo = 20;
55constexpr int32_t sInputEventId = 5;
56constexpr int32_t sLayerIdOne = 1;
57constexpr int32_t sLayerIdTwo = 2;
58constexpr GameMode sGameMode = GameMode::Unsupported;
Pascal Muetschardac7bcd92023-10-03 15:05:36 +020059constexpr Fps RR_11 = Fps::fromPeriodNsecs(11);
60constexpr Fps RR_30 = Fps::fromPeriodNsecs(30);
Ady Abraham57a8ab42023-01-26 15:28:19 -080061
Adithya Srinivasanf279e042020-08-17 14:56:27 -070062class FrameTimelineTest : public testing::Test {
63public:
64 FrameTimelineTest() {
65 const ::testing::TestInfo* const test_info =
66 ::testing::UnitTest::GetInstance()->current_test_info();
67 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
68 }
69
70 ~FrameTimelineTest() {
71 const ::testing::TestInfo* const test_info =
72 ::testing::UnitTest::GetInstance()->current_test_info();
73 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
74 }
75
Adithya Srinivasan01189672020-10-20 14:23:05 -070076 static void SetUpTestSuite() {
77 // Need to initialize tracing in process for testing, and only once per test suite.
78 perfetto::TracingInitArgs args;
79 args.backends = perfetto::kInProcessBackend;
80 perfetto::Tracing::Initialize(args);
81 }
82
Adithya Srinivasanf279e042020-08-17 14:56:27 -070083 void SetUp() override {
Ady Abraham57f8e182022-03-08 15:54:33 -080084 constexpr bool kUseBootTimeClock = true;
Alec Mouri9a29e672020-09-14 12:39:14 -070085 mTimeStats = std::make_shared<mock::TimeStats>();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000086 mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats, kSurfaceFlingerPid,
Ady Abraham57f8e182022-03-08 15:54:33 -080087 kTestThresholds, !kUseBootTimeClock);
Adithya Srinivasan01189672020-10-20 14:23:05 -070088 mFrameTimeline->registerDataSource();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070089 mTokenManager = &mFrameTimeline->mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000090 mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
Adithya Srinivasan2d736322020-10-01 16:53:48 -070091 maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +000092 maxTokens = mTokenManager->kMaxTokens;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070093 }
94
Adithya Srinivasan01189672020-10-20 14:23:05 -070095 // Each tracing session can be used for a single block of Start -> Stop.
96 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
97 perfetto::TraceConfig cfg;
98 cfg.set_duration_ms(500);
99 cfg.add_buffers()->set_size_kb(1024);
100 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
101 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
102
103 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
104 tracingSession->Setup(cfg);
105 return tracingSession;
106 }
107
108 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
109 perfetto::TracingSession* tracingSession) {
110 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
111 perfetto::protos::Trace trace;
112 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
113
114 std::vector<perfetto::protos::TracePacket> packets;
115 for (const auto& packet : trace.packet()) {
116 if (!packet.has_frame_timeline_event()) {
117 continue;
118 }
119 packets.emplace_back(packet);
120 }
121 return packets;
122 }
123
Ady Abraham57a8ab42023-01-26 15:28:19 -0800124 void addEmptySurfaceFrame() {
125 auto surfaceFrame =
126 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
127 sLayerNameOne, sLayerNameOne,
128 /*isBuffer*/ false, sGameMode);
129 mFrameTimeline->addSurfaceFrame(std::move(surfaceFrame));
130 }
131
Adithya Srinivasan01189672020-10-20 14:23:05 -0700132 void addEmptyDisplayFrame() {
133 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000134 // Trigger a flushPresentFence by calling setSfPresent for the next frame
Adithya Srinivasan01189672020-10-20 14:23:05 -0700135 mFrameTimeline->setSfPresent(2500, presentFence1);
136 }
137
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000138 void flushTokens() {
139 for (size_t i = 0; i < maxTokens; i++) {
140 mTokenManager->generateTokenForPredictions({});
141 }
142 EXPECT_EQ(getPredictions().size(), maxTokens);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700143 }
144
145 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
146 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800147 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
148 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700149 }
150
151 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
152 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
153 return mFrameTimeline->mDisplayFrames[idx];
154 }
155
156 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
157 return a.startTime == b.startTime && a.endTime == b.endTime &&
158 a.presentTime == b.presentTime;
159 }
160
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000161 const std::map<int64_t, TimelineItem>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700162 return mTokenManager->mPredictions;
163 }
164
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000165 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700166 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
167 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
168 }
169
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000170 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
171
172 void flushTrace() {
173 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
174 FrameTimelineDataSource::Trace(
175 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
176 }
177
Alec Mouri9a29e672020-09-14 12:39:14 -0700178 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700179 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
180 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000181 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700182 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700183 uint32_t* maxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000184 size_t maxTokens;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000185 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasanead17162021-02-18 02:17:37 +0000186 static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan54996e22021-06-25 22:26:45 +0000187 static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(0ns).count();
Adithya Srinivasanead17162021-02-18 02:17:37 +0000188 static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800189 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
190 kDeadlineThreshold,
191 kStartThreshold};
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700192};
193
194TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
195 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000196 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000197 flushTokens();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700198 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
199 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
200
201 // token1 should have expired
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700202 EXPECT_EQ(predictions.has_value(), false);
203
204 predictions = mTokenManager->getPredictionsForToken(token2);
205 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
206}
207
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700208TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800209 auto surfaceFrame1 =
210 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000211 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000212 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -0800213 auto surfaceFrame2 =
214 mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000215 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000216 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700217 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
218 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
219}
220
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700221TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800222 auto surfaceFrame =
223 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000224 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000225 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700226 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
227}
228
229TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
230 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000231 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -0800232 FrameTimelineInfo ftInfo;
233 ftInfo.vsyncId = token1;
234 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000235 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800236 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
237 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000238 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700239
240 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
241}
242
243TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
244 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800245 FrameTimelineInfo ftInfo;
246 ftInfo.vsyncId = token1;
247 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000248 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800249 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
250 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000251 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700252
253 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
254 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
255}
256
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000257TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
258 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
259 constexpr int32_t inputEventId = 1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800260 FrameTimelineInfo ftInfo;
261 ftInfo.vsyncId = token1;
262 ftInfo.inputEventId = inputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000263 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800264 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
265 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000266 /*isBuffer*/ true, sGameMode);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000267
268 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
269}
270
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700271TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
272 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700273 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800274 FrameTimelineInfo ftInfo;
275 ftInfo.vsyncId = token1;
276 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000277 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800278 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
279 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000280 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700281
282 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200283 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000284 surfaceFrame1->setDropTime(12);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800285 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
286 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700287 mFrameTimeline->setSfPresent(25, presentFence1);
288 presentFence1->signalForTest(30);
289
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000290 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700291
292 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
293 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000294 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
295 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700296 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
297}
298
299TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800300 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800301 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700302 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
303 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700304 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800305 FrameTimelineInfo ftInfo;
306 ftInfo.vsyncId = surfaceFrameToken1;
307 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700308 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800309 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
310 sLayerNameOne, sLayerNameOne,
311 /*isBuffer*/ true, sGameMode);
Alec Mouri9a29e672020-09-14 12:39:14 -0700312 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800313 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdTwo,
314 sLayerNameTwo, sLayerNameTwo,
315 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200316 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800317 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
318 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
319 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
320 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700321 mFrameTimeline->setSfPresent(26, presentFence1);
322 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800323 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
324 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700325 presentFence1->signalForTest(42);
326
327 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800328 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700329 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
330 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
331
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000332 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700333
334 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800335 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700336 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
337 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100338 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
Ying Wei96eb5352023-11-21 17:37:21 +0000339 EXPECT_NE(surfaceFrame1->getJankSeverityType(), std::nullopt);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100340 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Ying Wei96eb5352023-11-21 17:37:21 +0000341 EXPECT_NE(surfaceFrame2->getJankSeverityType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700342}
343
Ady Abraham14beed72024-05-15 17:16:45 -0700344TEST_F(FrameTimelineTest, displayFrameSkippedComposition) {
345 // Layer specific increment
346 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(1);
347 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
348 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
349 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
350 FrameTimelineInfo ftInfo;
351 ftInfo.vsyncId = surfaceFrameToken1;
352 ftInfo.inputEventId = sInputEventId;
353 auto surfaceFrame1 =
354 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
355 sLayerNameOne, sLayerNameOne,
356 /*isBuffer*/ true, sGameMode);
357 auto surfaceFrame2 =
358 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdTwo,
359 sLayerNameTwo, sLayerNameTwo,
360 /*isBuffer*/ true, sGameMode);
361
362 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
363 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
364 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
365 mFrameTimeline->onCommitNotComposited();
366
367 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 30);
368 ASSERT_NE(surfaceFrame1->getJankType(), std::nullopt);
369 EXPECT_EQ(*surfaceFrame1->getJankType(), JankType::None);
370 ASSERT_NE(surfaceFrame1->getJankSeverityType(), std::nullopt);
371 EXPECT_EQ(*surfaceFrame1->getJankSeverityType(), JankSeverityType::None);
372
373 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
374 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
375 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
376 mFrameTimeline->setSfPresent(26, presentFence1);
377
378 auto displayFrame = getDisplayFrame(0);
379 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 0);
380 presentFence1->signalForTest(42);
381
382 // Fences haven't been flushed yet, so it should be 0
383 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
384 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
385
386 addEmptyDisplayFrame();
387
388 // Fences have flushed, so the present timestamps should be updated
389 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
390 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
391 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
392 EXPECT_NE(surfaceFrame2->getJankSeverityType(), std::nullopt);
393}
394
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700395TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
396 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
397 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800398 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800399 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800400 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700401 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700402 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
403 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
404 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
405 int64_t sfToken = mTokenManager->generateTokenForPredictions(
406 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800407 FrameTimelineInfo ftInfo;
408 ftInfo.vsyncId = surfaceFrameToken;
409 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700410 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800411 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000412 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000413 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200414 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800415 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
416 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700417 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
418 presentFence->signalForTest(32 + frameTimeFactor);
419 frameTimeFactor += 30;
420 }
421 auto displayFrame0 = getDisplayFrame(0);
422
423 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800424 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700425
426 // Add one more display frame
427 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
428 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
429 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
430 int64_t sfToken = mTokenManager->generateTokenForPredictions(
431 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800432 FrameTimelineInfo ftInfo;
433 ftInfo.vsyncId = surfaceFrameToken;
434 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700435 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800436 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
437 sLayerNameOne, sLayerNameOne,
438 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200439 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800440 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
441 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700442 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
443 presentFence->signalForTest(32 + frameTimeFactor);
444 displayFrame0 = getDisplayFrame(0);
445
446 // The window should have slided by 1 now and the previous 0th display frame
447 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800448 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700449}
450
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700451TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000452 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
453 "acquireFenceAfterQueue",
454 "acquireFenceAfterQueue",
455 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700456 surfaceFrame->setActualQueueTime(123);
457 surfaceFrame->setAcquireFenceTime(456);
458 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
459}
460
461TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000462 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
463 "acquireFenceAfterQueue",
464 "acquireFenceAfterQueue",
465 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700466 surfaceFrame->setActualQueueTime(456);
467 surfaceFrame->setAcquireFenceTime(123);
468 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
469}
470
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700471TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
472 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
473 presentFence->signalForTest(2);
474
475 // Size shouldn't exceed maxDisplayFrames - 64
476 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700477 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800478 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000479 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000480 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700481 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200482 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800483 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
484 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700485 mFrameTimeline->setSfPresent(27, presentFence);
486 }
487 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
488
489 // Increase the size to 256
490 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000491 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700492
493 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700494 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800495 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000496 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000497 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700498 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200499 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800500 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
501 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700502 mFrameTimeline->setSfPresent(27, presentFence);
503 }
504 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
505
506 // Shrink the size to 128
507 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000508 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700509
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}
Alec Mouri9a29e672020-09-14 12:39:14 -0700523
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000524TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200525 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000526
527 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
528 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
529 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800530 FrameTimelineInfo ftInfo;
531 ftInfo.vsyncId = surfaceFrameToken1;
532 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000533
534 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800535 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
536 sLayerNameOne, sLayerNameOne,
537 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200538 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000539 surfaceFrame1->setAcquireFenceTime(20);
540 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
541 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
542
543 mFrameTimeline->setSfPresent(59, presentFence1);
544 presentFence1->signalForTest(-1);
545 addEmptyDisplayFrame();
546
547 auto displayFrame0 = getDisplayFrame(0);
Ady Abrahamfcb16862022-10-10 14:35:21 -0700548 EXPECT_EQ(displayFrame0->getActuals().presentTime, 59);
Ady Abrahamb1e10d12023-03-13 15:23:54 -0700549 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +0000550 EXPECT_EQ(displayFrame0->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000551 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
552 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +0000553 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000554}
555
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800556// Tests related to TimeStats
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000557TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200558 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000559 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
560 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
561 int64_t surfaceFrameToken1 = -1;
562 int64_t sfToken1 = -1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800563 FrameTimelineInfo ftInfo;
564 ftInfo.vsyncId = surfaceFrameToken1;
565 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000566
567 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800568 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
569 sLayerNameOne, sLayerNameOne,
570 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200571 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000572 surfaceFrame1->setAcquireFenceTime(20);
573 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
574 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
575 presentFence1->signalForTest(70);
576
577 mFrameTimeline->setSfPresent(59, presentFence1);
578}
579
Alec Mouri9a29e672020-09-14 12:39:14 -0700580TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200581 Fps refreshRate = RR_11;
Alec Mouri9a29e672020-09-14 12:39:14 -0700582 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800583 incrementJankyFrames(
584 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000585 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000586 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800587 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700588 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000589 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
590 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800591 FrameTimelineInfo ftInfo;
592 ftInfo.vsyncId = surfaceFrameToken1;
593 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000594
Alec Mouri9a29e672020-09-14 12:39:14 -0700595 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800596 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
597 sLayerNameOne, sLayerNameOne,
598 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200599 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000600 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800601 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
602 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000603 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700604
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000605 mFrameTimeline->setSfPresent(62, presentFence1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700606}
607
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000608TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfGpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200609 Fps refreshRate = RR_11;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000610 EXPECT_CALL(*mTimeStats,
611 incrementJankyFrames(
612 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000613 sLayerNameOne, sGameMode,
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000614 JankType::SurfaceFlingerGpuDeadlineMissed, 4, 10,
615 0}));
616 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
617 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
618 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
619 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800620 FrameTimelineInfo ftInfo;
621 ftInfo.vsyncId = surfaceFrameToken1;
622 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000623
624 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800625 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
626 sLayerNameOne, sLayerNameOne,
627 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200628 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000629 surfaceFrame1->setAcquireFenceTime(20);
630 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
631 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
632 gpuFence1->signalForTest(64);
633 presentFence1->signalForTest(70);
634
635 mFrameTimeline->setSfPresent(59, presentFence1, gpuFence1);
636}
637
Alec Mouri9a29e672020-09-14 12:39:14 -0700638TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200639 Fps refreshRate = RR_30;
Alec Mouri9a29e672020-09-14 12:39:14 -0700640 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800641 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000642 sLayerNameOne, sGameMode,
643 JankType::DisplayHAL, -4, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800644
Alec Mouri9a29e672020-09-14 12:39:14 -0700645 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000646 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
647 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800648 FrameTimelineInfo ftInfo;
649 ftInfo.vsyncId = surfaceFrameToken1;
650 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000651
Alec Mouri9a29e672020-09-14 12:39:14 -0700652 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800653 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
654 sLayerNameOne, sLayerNameOne,
655 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200656 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800657 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000658 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800659 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000660 presentFence1->signalForTest(90);
661 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800662 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +0000663 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Alec Mouri9a29e672020-09-14 12:39:14 -0700664}
665
666TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700667 Fps refreshRate = 11_Hz;
Alec Mouri9a29e672020-09-14 12:39:14 -0700668 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000669 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000670 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000671 JankType::AppDeadlineMissed, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000672 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700673 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000674 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
675 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800676 FrameTimelineInfo ftInfo;
677 ftInfo.vsyncId = surfaceFrameToken1;
678 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000679
Alec Mouri9a29e672020-09-14 12:39:14 -0700680 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800681 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
682 sLayerNameOne, sLayerNameOne,
683 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000684 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200685 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700686
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800687 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
688 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000689 presentFence1->signalForTest(90);
690 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100691
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800692 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000693 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Partial);
Alec Mouri9a29e672020-09-14 12:39:14 -0700694}
695
Adithya Srinivasanead17162021-02-18 02:17:37 +0000696TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000697 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000698 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000699 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000700 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000701 JankType::SurfaceFlingerScheduling,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000702 -4, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000703 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000704 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
705 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800706 FrameTimelineInfo ftInfo;
707 ftInfo.vsyncId = surfaceFrameToken1;
708 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000709
Adithya Srinivasanead17162021-02-18 02:17:37 +0000710 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800711 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
712 sLayerNameOne, sLayerNameOne,
713 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000714 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200715 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000716
717 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
718 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000719 presentFence1->signalForTest(60);
720 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000721
722 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +0000723 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000724}
725
726TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000727 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000728 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000729 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000730 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000731 JankType::PredictionError, -4, 5,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000732 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000733 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000734 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
735 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800736 FrameTimelineInfo ftInfo;
737 ftInfo.vsyncId = surfaceFrameToken1;
738 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000739
Adithya Srinivasanead17162021-02-18 02:17:37 +0000740 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800741 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
742 sLayerNameOne, sLayerNameOne,
743 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000744 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200745 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000746
747 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
748 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000749 presentFence1->signalForTest(65);
750 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000751
752 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +0000753 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000754}
755
756TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000757 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000758 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000759 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000760 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000761 JankType::BufferStuffing, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000762 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000763 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000764 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
765 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800766 FrameTimelineInfo ftInfo;
767 ftInfo.vsyncId = surfaceFrameToken1;
768 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000769
Adithya Srinivasanead17162021-02-18 02:17:37 +0000770 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800771 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
772 sLayerNameOne, sLayerNameOne,
773 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000774 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200775 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000776
777 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000778 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000779 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000780 presentFence1->signalForTest(90);
781 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000782
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000783 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +0000784 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000785}
786
Alec Mouri363faf02021-01-29 16:34:55 -0800787TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200788 Fps refreshRate = RR_11;
789 Fps renderRate = RR_30;
Alec Mouri363faf02021-01-29 16:34:55 -0800790 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000791 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne,
792 sLayerNameOne, sGameMode,
793 JankType::AppDeadlineMissed, -4, 0,
794 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800795 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000796 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
797 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800798 FrameTimelineInfo ftInfo;
799 ftInfo.vsyncId = surfaceFrameToken1;
800 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000801
Alec Mouri363faf02021-01-29 16:34:55 -0800802 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800803 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
804 sLayerNameOne, sLayerNameOne,
805 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000806 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200807 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800808
809 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
810 surfaceFrame1->setRenderRate(renderRate);
811 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000812 presentFence1->signalForTest(90);
813 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800814
815 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000816 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Alec Mouri363faf02021-01-29 16:34:55 -0800817}
818
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000819TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200820 Fps refreshRate = RR_11;
821 Fps renderRate = RR_30;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000822
823 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000824 incrementJankyFrames(
825 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000826 sGameMode,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000827 JankType::Unknown | JankType::AppDeadlineMissed,
Adithya Srinivasande272452021-04-10 00:21:00 +0000828 0, 0, 25}));
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000829 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
830 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
831 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800832 FrameTimelineInfo ftInfo;
833 ftInfo.vsyncId = surfaceFrameToken1;
834 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000835
836 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800837 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
838 sLayerNameOne, sLayerNameOne,
839 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000840 surfaceFrame1->setAcquireFenceTime(45);
841 // Trigger a prediction expiry
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000842 flushTokens();
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200843 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000844
845 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
846 surfaceFrame1->setRenderRate(renderRate);
847 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
848 presentFence1->signalForTest(90);
849 mFrameTimeline->setSfPresent(86, presentFence1);
850
851 auto displayFrame = getDisplayFrame(0);
852 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +0000853 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000854 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
855 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
856 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
857
858 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000859 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000860 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000861}
862
Adithya Srinivasan01189672020-10-20 14:23:05 -0700863/*
864 * Tracing Tests
865 *
866 * Trace packets are flushed all the way only when the next packet is traced.
867 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
868 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
869 * will have additional empty frames created for this reason.
870 */
871TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
872 auto tracingSession = getTracingSessionForTest();
873 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700874 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800875 FrameTimelineInfo ftInfo;
876 ftInfo.vsyncId = token1;
877 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000878 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800879 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
880 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000881 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700882
883 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200884 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800885 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
886 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700887 mFrameTimeline->setSfPresent(25, presentFence1);
888 presentFence1->signalForTest(30);
889
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000890 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700891
892 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000893 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700894}
895
896TEST_F(FrameTimelineTest, tracing_sanityTest) {
897 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800898 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800899 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700900 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700901
902 tracingSession->StartBlocking();
903 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
904 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800905 FrameTimelineInfo ftInfo;
906 ftInfo.vsyncId = token1;
907 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000908 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800909 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
910 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000911 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700912
913 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200914 mFrameTimeline->setSfWakeUp(token2, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800915 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
916 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700917 mFrameTimeline->setSfPresent(25, presentFence1);
918 presentFence1->signalForTest(30);
919
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000920 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000921 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700922 tracingSession->StopBlocking();
923
924 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000925 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000926 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700927}
928
929TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
930 auto tracingSession = getTracingSessionForTest();
931 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700932
933 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700934
935 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200936 mFrameTimeline->setSfWakeUp(-1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700937 mFrameTimeline->setSfPresent(25, presentFence1);
938 presentFence1->signalForTest(30);
939
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000940 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000941 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700942 tracingSession->StopBlocking();
943
944 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000945 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700946}
947
948TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
949 auto tracingSession = getTracingSessionForTest();
950 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700951
952 tracingSession->StartBlocking();
953 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -0800954 auto surfaceFrame1 =
955 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000956 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000957 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700958
959 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200960 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800961 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
962 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700963 mFrameTimeline->setSfPresent(25, presentFence1);
964 presentFence1->signalForTest(30);
965
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000966 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000967 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700968 tracingSession->StopBlocking();
969
970 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000971 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
972 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000973 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700974}
975
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000976ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
977 pid_t pid) {
978 ProtoExpectedDisplayFrameStart proto;
979 proto.set_cookie(cookie);
980 proto.set_token(token);
981 proto.set_pid(pid);
982 return proto;
983}
984
985ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
986 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Ying Wei96eb5352023-11-21 17:37:21 +0000987 bool gpuComposition, ProtoJankType jankType, ProtoJankSeverityType jankSeverityType,
988 ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000989 ProtoActualDisplayFrameStart proto;
990 proto.set_cookie(cookie);
991 proto.set_token(token);
992 proto.set_pid(pid);
993 proto.set_present_type(presentType);
994 proto.set_on_time_finish(onTimeFinish);
995 proto.set_gpu_composition(gpuComposition);
996 proto.set_jank_type(jankType);
Ying Wei96eb5352023-11-21 17:37:21 +0000997 proto.set_jank_severity_type(jankSeverityType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000998 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000999 return proto;
1000}
1001
1002ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
1003 int64_t displayFrameToken,
1004 pid_t pid,
1005 std::string layerName) {
1006 ProtoExpectedSurfaceFrameStart proto;
1007 proto.set_cookie(cookie);
1008 proto.set_token(token);
1009 proto.set_display_frame_token(displayFrameToken);
1010 proto.set_pid(pid);
1011 proto.set_layer_name(layerName);
1012 return proto;
1013}
1014
1015ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
1016 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
1017 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Ying Wei96eb5352023-11-21 17:37:21 +00001018 ProtoJankType jankType, ProtoJankSeverityType jankSeverityType,
1019 ProtoPredictionType predictionType, bool isBuffer) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001020 ProtoActualSurfaceFrameStart proto;
1021 proto.set_cookie(cookie);
1022 proto.set_token(token);
1023 proto.set_display_frame_token(displayFrameToken);
1024 proto.set_pid(pid);
1025 proto.set_layer_name(layerName);
1026 proto.set_present_type(presentType);
1027 proto.set_on_time_finish(onTimeFinish);
1028 proto.set_gpu_composition(gpuComposition);
1029 proto.set_jank_type(jankType);
Ying Wei96eb5352023-11-21 17:37:21 +00001030 proto.set_jank_severity_type(jankSeverityType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001031 proto.set_prediction_type(predictionType);
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001032 proto.set_is_buffer(isBuffer);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001033 return proto;
1034}
1035
1036ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
1037 ProtoFrameEnd proto;
1038 proto.set_cookie(cookie);
1039 return proto;
1040}
1041
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001042void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
1043 const ProtoExpectedDisplayFrameStart& source) {
1044 ASSERT_TRUE(received.has_cookie());
1045 EXPECT_EQ(received.cookie(), source.cookie());
1046
Adithya Srinivasan01189672020-10-20 14:23:05 -07001047 ASSERT_TRUE(received.has_token());
1048 EXPECT_EQ(received.token(), source.token());
1049
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001050 ASSERT_TRUE(received.has_pid());
1051 EXPECT_EQ(received.pid(), source.pid());
1052}
1053
1054void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
1055 const ProtoActualDisplayFrameStart& source) {
1056 ASSERT_TRUE(received.has_cookie());
1057 EXPECT_EQ(received.cookie(), source.cookie());
1058
1059 ASSERT_TRUE(received.has_token());
1060 EXPECT_EQ(received.token(), source.token());
1061
1062 ASSERT_TRUE(received.has_pid());
1063 EXPECT_EQ(received.pid(), source.pid());
1064
Adithya Srinivasan01189672020-10-20 14:23:05 -07001065 ASSERT_TRUE(received.has_present_type());
1066 EXPECT_EQ(received.present_type(), source.present_type());
1067 ASSERT_TRUE(received.has_on_time_finish());
1068 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1069 ASSERT_TRUE(received.has_gpu_composition());
1070 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1071 ASSERT_TRUE(received.has_jank_type());
1072 EXPECT_EQ(received.jank_type(), source.jank_type());
Ying Wei96eb5352023-11-21 17:37:21 +00001073 ASSERT_TRUE(received.has_jank_severity_type());
1074 EXPECT_EQ(received.jank_severity_type(), source.jank_severity_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001075 ASSERT_TRUE(received.has_prediction_type());
1076 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001077}
1078
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001079void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
1080 const ProtoExpectedSurfaceFrameStart& source) {
1081 ASSERT_TRUE(received.has_cookie());
1082 EXPECT_EQ(received.cookie(), source.cookie());
1083
Adithya Srinivasan01189672020-10-20 14:23:05 -07001084 ASSERT_TRUE(received.has_token());
1085 EXPECT_EQ(received.token(), source.token());
1086
1087 ASSERT_TRUE(received.has_display_frame_token());
1088 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1089
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001090 ASSERT_TRUE(received.has_pid());
1091 EXPECT_EQ(received.pid(), source.pid());
1092
1093 ASSERT_TRUE(received.has_layer_name());
1094 EXPECT_EQ(received.layer_name(), source.layer_name());
1095}
1096
1097void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
1098 const ProtoActualSurfaceFrameStart& source) {
1099 ASSERT_TRUE(received.has_cookie());
1100 EXPECT_EQ(received.cookie(), source.cookie());
1101
1102 ASSERT_TRUE(received.has_token());
1103 EXPECT_EQ(received.token(), source.token());
1104
1105 ASSERT_TRUE(received.has_display_frame_token());
1106 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1107
1108 ASSERT_TRUE(received.has_pid());
1109 EXPECT_EQ(received.pid(), source.pid());
1110
1111 ASSERT_TRUE(received.has_layer_name());
1112 EXPECT_EQ(received.layer_name(), source.layer_name());
1113
Adithya Srinivasan01189672020-10-20 14:23:05 -07001114 ASSERT_TRUE(received.has_present_type());
1115 EXPECT_EQ(received.present_type(), source.present_type());
1116 ASSERT_TRUE(received.has_on_time_finish());
1117 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1118 ASSERT_TRUE(received.has_gpu_composition());
1119 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1120 ASSERT_TRUE(received.has_jank_type());
1121 EXPECT_EQ(received.jank_type(), source.jank_type());
Ying Wei96eb5352023-11-21 17:37:21 +00001122 ASSERT_TRUE(received.has_jank_severity_type());
1123 EXPECT_EQ(received.jank_severity_type(), source.jank_severity_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001124 ASSERT_TRUE(received.has_prediction_type());
1125 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001126 ASSERT_TRUE(received.has_is_buffer());
1127 EXPECT_EQ(received.is_buffer(), source.is_buffer());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001128}
Adithya Srinivasan01189672020-10-20 14:23:05 -07001129
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001130void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
1131 ASSERT_TRUE(received.has_cookie());
1132 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001133}
1134
Sally Qi2269a692024-05-17 18:02:28 -07001135TEST_F(FrameTimelineTest, traceDisplayFrameNoSkipped) {
1136 // setup 2 display frames
1137 // DF 1: [22, 30] -> [0, 11]
1138 // DF 2: [82, 90] -> SF [5, 16]
1139 auto tracingSession = getTracingSessionForTest();
1140 tracingSession->StartBlocking();
1141 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1142 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 100});
1143 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({0, 11, 25});
1144 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1145 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1146
1147 int64_t traceCookie = snoopCurrentTraceCookie();
1148
1149 // set up 1st display frame
1150 FrameTimelineInfo ftInfo1;
1151 ftInfo1.vsyncId = surfaceFrameToken1;
1152 ftInfo1.inputEventId = sInputEventId;
1153 auto surfaceFrame1 =
1154 mFrameTimeline->createSurfaceFrameForToken(ftInfo1, sPidOne, sUidOne, sLayerIdOne,
1155 sLayerNameOne, sLayerNameOne,
1156 /*isBuffer*/ true, sGameMode);
1157 surfaceFrame1->setAcquireFenceTime(11);
1158 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_30);
1159 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1160 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1161 mFrameTimeline->setSfPresent(30, presentFence1);
1162 presentFence1->signalForTest(40);
1163
1164 // Trigger a flush by finalizing the next DisplayFrame
1165 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1166 FrameTimelineInfo ftInfo2;
1167 ftInfo2.vsyncId = surfaceFrameToken2;
1168 ftInfo2.inputEventId = sInputEventId;
1169 auto surfaceFrame2 =
1170 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1171 sLayerNameOne, sLayerNameOne,
1172 /*isBuffer*/ true, sGameMode);
1173
1174 // set up 2nd display frame
1175 surfaceFrame2->setAcquireFenceTime(16);
1176 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_11, RR_30);
1177 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1178 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1179 mFrameTimeline->setSfPresent(90, presentFence2);
1180 presentFence2->signalForTest(100);
1181
1182 // the token of skipped Display Frame
1183 auto protoSkippedActualDisplayFrameStart =
1184 createProtoActualDisplayFrameStart(traceCookie + 9, 0, kSurfaceFlingerPid,
1185 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1186 FrameTimelineEvent::JANK_DROPPED,
1187 FrameTimelineEvent::SEVERITY_NONE,
1188 FrameTimelineEvent::PREDICTION_VALID);
1189 auto protoSkippedActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 9);
1190
1191 // Trigger a flush by finalizing the next DisplayFrame
1192 addEmptyDisplayFrame();
1193 flushTrace();
1194 tracingSession->StopBlocking();
1195
1196 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1197 // 8 Valid Display Frames + 8 Valid Surface Frames + no Skipped Display Frames
1198 EXPECT_EQ(packets.size(), 16u);
1199}
1200
Sally Qiaa107742023-09-29 14:53:14 -07001201TEST_F(FrameTimelineTest, traceDisplayFrameSkipped) {
Sally Qif5721252023-11-17 11:14:53 -08001202 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::add_sf_skipped_frames_to_trace,
1203 true);
1204
Sally Qiaa107742023-09-29 14:53:14 -07001205 // setup 2 display frames
1206 // DF 1: [22,40] -> [5, 40]
1207 // DF : [36, 70] (Skipped one, added by the trace)
1208 // DF 2: [82, 100] -> SF [25, 70]
1209 auto tracingSession = getTracingSessionForTest();
1210 tracingSession->StartBlocking();
1211 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1212 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 100});
1213 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1214 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1215 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1216
1217 int64_t traceCookie = snoopCurrentTraceCookie();
1218
1219 // set up 1st display frame
1220 FrameTimelineInfo ftInfo1;
1221 ftInfo1.vsyncId = surfaceFrameToken1;
1222 ftInfo1.inputEventId = sInputEventId;
1223 auto surfaceFrame1 =
1224 mFrameTimeline->createSurfaceFrameForToken(ftInfo1, sPidOne, sUidOne, sLayerIdOne,
1225 sLayerNameOne, sLayerNameOne,
1226 /*isBuffer*/ true, sGameMode);
1227 surfaceFrame1->setAcquireFenceTime(16);
1228 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_30);
1229 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1230 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1231 mFrameTimeline->setSfPresent(30, presentFence1);
1232 presentFence1->signalForTest(40);
1233
1234 // Trigger a flush by finalizing the next DisplayFrame
1235 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1236 FrameTimelineInfo ftInfo2;
1237 ftInfo2.vsyncId = surfaceFrameToken2;
1238 ftInfo2.inputEventId = sInputEventId;
1239 auto surfaceFrame2 =
1240 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1241 sLayerNameOne, sLayerNameOne,
1242 /*isBuffer*/ true, sGameMode);
1243
1244 // set up 2nd display frame
1245 surfaceFrame2->setAcquireFenceTime(36);
1246 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_11, RR_30);
1247 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1248 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1249 mFrameTimeline->setSfPresent(90, presentFence2);
1250 presentFence2->signalForTest(100);
1251
1252 // the token of skipped Display Frame
1253 auto protoSkippedActualDisplayFrameStart =
1254 createProtoActualDisplayFrameStart(traceCookie + 9, 0, kSurfaceFlingerPid,
1255 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1256 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001257 FrameTimelineEvent::SEVERITY_NONE,
Sally Qiaa107742023-09-29 14:53:14 -07001258 FrameTimelineEvent::PREDICTION_VALID);
1259 auto protoSkippedActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 9);
1260
1261 // Trigger a flush by finalizing the next DisplayFrame
1262 addEmptyDisplayFrame();
1263 flushTrace();
1264 tracingSession->StopBlocking();
1265
1266 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1267 // 8 Valid Display Frames + 8 Valid Surface Frames + 2 Skipped Display Frames
1268 EXPECT_EQ(packets.size(), 18u);
1269
1270 // Packet - 16: Actual skipped Display Frame Start
1271 // the timestamp should be equal to the 2nd expected surface frame's end time
1272 const auto& packet16 = packets[16];
1273 ASSERT_TRUE(packet16.has_timestamp());
1274 EXPECT_EQ(packet16.timestamp(), 36u);
1275 ASSERT_TRUE(packet16.has_frame_timeline_event());
1276
1277 const auto& event16 = packet16.frame_timeline_event();
1278 const auto& actualSkippedDisplayFrameStart = event16.actual_display_frame_start();
1279 validateTraceEvent(actualSkippedDisplayFrameStart, protoSkippedActualDisplayFrameStart);
1280
1281 // Packet - 17: Actual skipped Display Frame End
1282 // the timestamp should be equal to the 2nd expected surface frame's present time
1283 const auto& packet17 = packets[17];
1284 ASSERT_TRUE(packet17.has_timestamp());
1285 EXPECT_EQ(packet17.timestamp(), 70u);
1286 ASSERT_TRUE(packet17.has_frame_timeline_event());
1287
1288 const auto& event17 = packet17.frame_timeline_event();
1289 const auto& actualSkippedDisplayFrameEnd = event17.frame_end();
1290 validateTraceEvent(actualSkippedDisplayFrameEnd, protoSkippedActualDisplayFrameEnd);
1291}
1292
Adithya Srinivasan01189672020-10-20 14:23:05 -07001293TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
1294 auto tracingSession = getTracingSessionForTest();
1295 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001296
1297 tracingSession->StartBlocking();
Ady Abraham57a8ab42023-01-26 15:28:19 -08001298
1299 // Add an empty surface frame so that display frame would get traced.
1300 addEmptySurfaceFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001301 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001302
1303 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001304 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001305 mFrameTimeline->setSfPresent(26, presentFence1);
1306 presentFence1->signalForTest(31);
1307
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001308 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001309 auto protoExpectedDisplayFrameStart =
1310 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1311 kSurfaceFlingerPid);
1312 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1313 auto protoActualDisplayFrameStart =
1314 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
1315 kSurfaceFlingerPid,
1316 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001317 FrameTimelineEvent::JANK_NONE,
Ying Wei96eb5352023-11-21 17:37:21 +00001318 FrameTimelineEvent::SEVERITY_NONE,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001319 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001320 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001321
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001322 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001323 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001324 tracingSession->StopBlocking();
1325
1326 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001327 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001328
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001329 // Packet - 0 : ExpectedDisplayFrameStart
1330 const auto& packet0 = packets[0];
1331 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001332 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001333 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001334
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001335 const auto& event0 = packet0.frame_timeline_event();
1336 ASSERT_TRUE(event0.has_expected_display_frame_start());
1337 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
1338 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
1339
1340 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
1341 const auto& packet1 = packets[1];
1342 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001343 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001344 ASSERT_TRUE(packet1.has_frame_timeline_event());
1345
1346 const auto& event1 = packet1.frame_timeline_event();
1347 ASSERT_TRUE(event1.has_frame_end());
1348 const auto& expectedDisplayFrameEnd = event1.frame_end();
1349 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
1350
1351 // Packet - 2 : ActualDisplayFrameStart
1352 const auto& packet2 = packets[2];
1353 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001354 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001355 ASSERT_TRUE(packet2.has_frame_timeline_event());
1356
1357 const auto& event2 = packet2.frame_timeline_event();
1358 ASSERT_TRUE(event2.has_actual_display_frame_start());
1359 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1360 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1361
1362 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1363 const auto& packet3 = packets[3];
1364 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001365 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001366 ASSERT_TRUE(packet3.has_frame_timeline_event());
1367
1368 const auto& event3 = packet3.frame_timeline_event();
1369 ASSERT_TRUE(event3.has_frame_end());
1370 const auto& actualDisplayFrameEnd = event3.frame_end();
1371 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001372}
1373
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001374TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1375 auto tracingSession = getTracingSessionForTest();
1376 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1377
1378 tracingSession->StartBlocking();
1379 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1380 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001381 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001382
Ady Abraham57a8ab42023-01-26 15:28:19 -08001383 // Add an empty surface frame so that display frame would get traced.
1384 addEmptySurfaceFrame();
1385
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001386 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001387 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001388 mFrameTimeline->setSfPresent(26, presentFence1);
1389 presentFence1->signalForTest(31);
1390
1391 int64_t traceCookie = snoopCurrentTraceCookie();
1392
1393 auto protoActualDisplayFrameStart =
1394 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1395 kSurfaceFlingerPid,
1396 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001397 false, FrameTimelineEvent::JANK_UNKNOWN,
Ying Wei96eb5352023-11-21 17:37:21 +00001398 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001399 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001400 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1401
1402 addEmptyDisplayFrame();
1403 flushTrace();
1404 tracingSession->StopBlocking();
1405
1406 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1407 // Only actual timeline packets should be in the trace
1408 EXPECT_EQ(packets.size(), 2u);
1409
1410 // Packet - 0 : ActualDisplayFrameStart
1411 const auto& packet0 = packets[0];
1412 ASSERT_TRUE(packet0.has_timestamp());
1413 EXPECT_EQ(packet0.timestamp(), 20u);
1414 ASSERT_TRUE(packet0.has_frame_timeline_event());
1415
1416 const auto& event0 = packet0.frame_timeline_event();
1417 ASSERT_TRUE(event0.has_actual_display_frame_start());
1418 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1419 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1420
1421 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1422 const auto& packet1 = packets[1];
1423 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001424 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001425 ASSERT_TRUE(packet1.has_frame_timeline_event());
1426
1427 const auto& event1 = packet1.frame_timeline_event();
1428 ASSERT_TRUE(event1.has_frame_end());
1429 const auto& actualDisplayFrameEnd = event1.frame_end();
1430 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1431}
1432
Adithya Srinivasan01189672020-10-20 14:23:05 -07001433TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1434 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001435 // Layer specific increment
Edgar Arriaga631e4252023-03-02 02:11:24 +00001436 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001437 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1438 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1439
1440 tracingSession->StartBlocking();
1441 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1442 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001443
Huihong Luo3bdef862022-03-03 11:57:19 -08001444 FrameTimelineInfo ftInfo;
1445 ftInfo.vsyncId = surfaceFrameToken;
1446 ftInfo.inputEventId = sInputEventId;
1447
Adithya Srinivasan01189672020-10-20 14:23:05 -07001448 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001449 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1450 sLayerNameOne, sLayerNameOne,
1451 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001452 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001453 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1454 sLayerNameOne, sLayerNameOne,
1455 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001456 surfaceFrame1->setActualQueueTime(10);
1457 surfaceFrame1->setDropTime(15);
1458
1459 surfaceFrame2->setActualQueueTime(15);
1460 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001461
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001462 // First 2 cookies will be used by the DisplayFrame
1463 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1464
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001465 auto protoDroppedSurfaceFrameExpectedStart =
1466 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1467 displayFrameToken1, sPidOne, sLayerNameOne);
1468 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1469 auto protoDroppedSurfaceFrameActualStart =
1470 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1471 displayFrameToken1, sPidOne, sLayerNameOne,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001472 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1473 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001474 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001475 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001476 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001477
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001478 auto protoPresentedSurfaceFrameExpectedStart =
1479 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1480 displayFrameToken1, sPidOne, sLayerNameOne);
1481 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1482 auto protoPresentedSurfaceFrameActualStart =
1483 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1484 displayFrameToken1, sPidOne, sLayerNameOne,
1485 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001486 FrameTimelineEvent::JANK_NONE,
Ying Wei96eb5352023-11-21 17:37:21 +00001487 FrameTimelineEvent::SEVERITY_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001488 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001489 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001490
1491 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001492 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001493 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1494 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001495 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001496 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001497 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001498 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001499
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001500 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001501 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001502 tracingSession->StopBlocking();
1503
1504 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001505 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1506 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001507
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001508 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001509 const auto& packet4 = packets[4];
1510 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001511 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001512 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001513
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001514 const auto& event4 = packet4.frame_timeline_event();
1515 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001516 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1517 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001518
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001519 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001520 const auto& packet5 = packets[5];
1521 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001522 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001523 ASSERT_TRUE(packet5.has_frame_timeline_event());
1524
1525 const auto& event5 = packet5.frame_timeline_event();
1526 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001527 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1528 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001529
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001530 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001531 const auto& packet6 = packets[6];
1532 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001533 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001534 ASSERT_TRUE(packet6.has_frame_timeline_event());
1535
1536 const auto& event6 = packet6.frame_timeline_event();
1537 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001538 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1539 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001540
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001541 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001542 const auto& packet7 = packets[7];
1543 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001544 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001545 ASSERT_TRUE(packet7.has_frame_timeline_event());
1546
1547 const auto& event7 = packet7.frame_timeline_event();
1548 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001549 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1550 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1551
1552 // Packet - 8 : ExpectedSurfaceFrameStart2
1553 const auto& packet8 = packets[8];
1554 ASSERT_TRUE(packet8.has_timestamp());
1555 EXPECT_EQ(packet8.timestamp(), 10u);
1556 ASSERT_TRUE(packet8.has_frame_timeline_event());
1557
1558 const auto& event8 = packet8.frame_timeline_event();
1559 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1560 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1561 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1562
1563 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1564 const auto& packet9 = packets[9];
1565 ASSERT_TRUE(packet9.has_timestamp());
1566 EXPECT_EQ(packet9.timestamp(), 25u);
1567 ASSERT_TRUE(packet9.has_frame_timeline_event());
1568
1569 const auto& event9 = packet9.frame_timeline_event();
1570 ASSERT_TRUE(event9.has_frame_end());
1571 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1572 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1573
1574 // Packet - 10 : ActualSurfaceFrameStart2
1575 const auto& packet10 = packets[10];
1576 ASSERT_TRUE(packet10.has_timestamp());
1577 EXPECT_EQ(packet10.timestamp(), 10u);
1578 ASSERT_TRUE(packet10.has_frame_timeline_event());
1579
1580 const auto& event10 = packet10.frame_timeline_event();
1581 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1582 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1583 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1584
1585 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1586 const auto& packet11 = packets[11];
1587 ASSERT_TRUE(packet11.has_timestamp());
1588 EXPECT_EQ(packet11.timestamp(), 20u);
1589 ASSERT_TRUE(packet11.has_frame_timeline_event());
1590
1591 const auto& event11 = packet11.frame_timeline_event();
1592 ASSERT_TRUE(event11.has_frame_end());
1593 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1594 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1595}
1596
Ady Abrahame43ff722022-02-15 14:44:25 -08001597TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredIsAppMissedDeadline) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001598 auto tracingSession = getTracingSessionForTest();
1599 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1600
1601 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001602 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1603 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1604 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001605 int64_t surfaceFrameToken =
1606 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1607
1608 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001609 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001610 FrameTimelineInfo ftInfo;
1611 ftInfo.vsyncId = surfaceFrameToken;
1612 ftInfo.inputEventId = 0;
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001613 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001614 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1615 sLayerNameOne, sLayerNameOne,
1616 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001617 surfaceFrame1->setActualQueueTime(appEndTime);
1618 surfaceFrame1->setAcquireFenceTime(appEndTime);
1619
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001620 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1621 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1622 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001623 int64_t displayFrameToken =
1624 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1625
1626 // First 2 cookies will be used by the DisplayFrame
1627 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1628
1629 auto protoActualSurfaceFrameStart =
1630 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1631 displayFrameToken, sPidOne, sLayerNameOne,
1632 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Ady Abrahame43ff722022-02-15 14:44:25 -08001633 false, FrameTimelineEvent::JANK_APP_DEADLINE_MISSED,
Ying Wei96eb5352023-11-21 17:37:21 +00001634 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001635 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001636 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1637
1638 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001639 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001640 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1641 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1642 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1643 presentFence1->signalForTest(sfPresentTime);
1644
1645 addEmptyDisplayFrame();
1646 flushTrace();
1647 tracingSession->StopBlocking();
1648
1649 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1650 // Display Frame 4 packets + SurfaceFrame 2 packets
1651 ASSERT_EQ(packets.size(), 6u);
1652
1653 // Packet - 4 : ActualSurfaceFrameStart
1654 const auto& packet4 = packets[4];
1655 ASSERT_TRUE(packet4.has_timestamp());
1656 EXPECT_EQ(packet4.timestamp(),
1657 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1658 ASSERT_TRUE(packet4.has_frame_timeline_event());
1659
1660 const auto& event4 = packet4.frame_timeline_event();
1661 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1662 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1663 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1664
1665 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1666 const auto& packet5 = packets[5];
1667 ASSERT_TRUE(packet5.has_timestamp());
1668 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1669 ASSERT_TRUE(packet5.has_frame_timeline_event());
1670
1671 const auto& event5 = packet5.frame_timeline_event();
1672 ASSERT_TRUE(event5.has_frame_end());
1673 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001674 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001675}
1676
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001677TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDroppedFramesTracedProperly) {
1678 auto tracingSession = getTracingSessionForTest();
1679 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1680
1681 tracingSession->StartBlocking();
1682 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1683 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1684 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
1685 int64_t surfaceFrameToken =
1686 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1687
1688 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001689 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001690 FrameTimelineInfo ftInfo;
1691 ftInfo.vsyncId = surfaceFrameToken;
1692 ftInfo.inputEventId = 0;
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001693 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001694 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1695 sLayerNameOne, sLayerNameOne,
1696 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001697
1698 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(22ms).count();
1699 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1700 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
1701 int64_t displayFrameToken =
1702 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1703
1704 // First 2 cookies will be used by the DisplayFrame
1705 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1706
1707 auto protoActualSurfaceFrameStart =
1708 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1709 displayFrameToken, sPidOne, sLayerNameOne,
1710 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001711 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001712 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001713 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001714 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1715
1716 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001717 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001718 surfaceFrame1->setDropTime(sfStartTime);
1719 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1720 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1721 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1722 presentFence1->signalForTest(sfPresentTime);
1723
1724 addEmptyDisplayFrame();
1725 flushTrace();
1726 tracingSession->StopBlocking();
1727
1728 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1729 // Display Frame 4 packets + SurfaceFrame 2 packets
1730 ASSERT_EQ(packets.size(), 6u);
1731
1732 // Packet - 4 : ActualSurfaceFrameStart
1733 const auto& packet4 = packets[4];
1734 ASSERT_TRUE(packet4.has_timestamp());
1735 EXPECT_EQ(packet4.timestamp(),
1736 static_cast<uint64_t>(sfStartTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1737 ASSERT_TRUE(packet4.has_frame_timeline_event());
1738
1739 const auto& event4 = packet4.frame_timeline_event();
1740 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1741 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1742 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1743
1744 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1745 const auto& packet5 = packets[5];
1746 ASSERT_TRUE(packet5.has_timestamp());
1747 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(sfStartTime));
1748 ASSERT_TRUE(packet5.has_frame_timeline_event());
1749
1750 const auto& event5 = packet5.frame_timeline_event();
1751 ASSERT_TRUE(event5.has_frame_end());
1752 const auto& actualSurfaceFrameEnd = event5.frame_end();
1753 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
1754}
1755
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001756// Tests for Jank classification
1757TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001758 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001759 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001760 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1761 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001762 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -08001763 FrameTimelineInfo ftInfo;
1764 ftInfo.vsyncId = surfaceFrameToken;
1765 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001766 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -08001767 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1768 sLayerNameOne, sLayerNameOne,
1769 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001770 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001771 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1772 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1773 mFrameTimeline->setSfPresent(26, presentFence1);
1774 auto displayFrame = getDisplayFrame(0);
1775 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1776 presentFence1->signalForTest(29);
1777
1778 // Fences haven't been flushed yet, so it should be 0
1779 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1780 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1781
1782 addEmptyDisplayFrame();
1783 displayFrame = getDisplayFrame(0);
1784
1785 // Fences have flushed, so the present timestamps should be updated
1786 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1787 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1788 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1789 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1790 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00001791 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001792}
1793
1794TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001795 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001796 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001797 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1798 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001799 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001800 mFrameTimeline->setSfPresent(26, presentFence1);
1801 auto displayFrame = getDisplayFrame(0);
1802 presentFence1->signalForTest(30);
1803
1804 // Fences for the first frame haven't been flushed yet, so it should be 0
1805 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1806
1807 // Trigger a flush by finalizing the next DisplayFrame
1808 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001809 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001810 mFrameTimeline->setSfPresent(56, presentFence2);
1811 displayFrame = getDisplayFrame(0);
1812
1813 // Fences for the first frame have flushed, so the present timestamps should be updated
1814 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1815 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1816 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1817 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00001818 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001819
1820 // Fences for the second frame haven't been flushed yet, so it should be 0
1821 auto displayFrame2 = getDisplayFrame(1);
1822 presentFence2->signalForTest(65);
1823 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001824 addEmptyDisplayFrame();
1825 displayFrame2 = getDisplayFrame(1);
1826
1827 // Fences for the second frame have flushed, so the present timestamps should be updated
1828 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1829 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1830 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1831 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00001832 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001833}
1834
1835TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001836 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001837 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001838 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1839 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001840 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001841 mFrameTimeline->setSfPresent(26, presentFence1);
1842 auto displayFrame = getDisplayFrame(0);
1843 presentFence1->signalForTest(50);
1844
1845 // Fences for the first frame haven't been flushed yet, so it should be 0
1846 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1847
1848 // Trigger a flush by finalizing the next DisplayFrame
1849 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001850 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001851 mFrameTimeline->setSfPresent(56, presentFence2);
1852 displayFrame = getDisplayFrame(0);
1853
1854 // Fences for the first frame have flushed, so the present timestamps should be updated
1855 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1856 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1857 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1858 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00001859 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001860
1861 // Fences for the second frame haven't been flushed yet, so it should be 0
1862 auto displayFrame2 = getDisplayFrame(1);
1863 presentFence2->signalForTest(75);
1864 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1865
1866 addEmptyDisplayFrame();
1867 displayFrame2 = getDisplayFrame(1);
1868
1869 // Fences for the second frame have flushed, so the present timestamps should be updated
1870 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1871 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1872 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1873 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00001874 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001875}
1876
1877TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001878 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1879 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001880 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001881
1882 mFrameTimeline->setSfPresent(22, presentFence1);
1883 auto displayFrame = getDisplayFrame(0);
1884 presentFence1->signalForTest(28);
1885
1886 // Fences haven't been flushed yet, so it should be 0
1887 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1888
1889 addEmptyDisplayFrame();
1890 displayFrame = getDisplayFrame(0);
1891
1892 // Fences have flushed, so the present timestamps should be updated
1893 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1894 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1895 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1896 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00001897 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001898}
1899
1900TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001901 /*
1902 * Case 1 - cpu time > vsync period but combined time > deadline > deadline -> cpudeadlinemissed
1903 * Case 2 - cpu time < vsync period but combined time > deadline -> gpudeadlinemissed
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001904 * Case 3 - previous frame ran longer -> sf_stuffing
1905 * Case 4 - Long cpu under SF stuffing -> cpudeadlinemissed
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001906 */
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001907 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001908 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001909 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1910 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001911 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1912 auto gpuFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001913 auto gpuFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1914 auto gpuFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001915 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001916 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001917 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1918 int64_t sfToken4 = mTokenManager->generateTokenForPredictions({112, 120, 120});
1919
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001920 // case 1 - cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001921 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001922 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
1923 auto displayFrame0 = getDisplayFrame(0);
1924 gpuFence1->signalForTest(36);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001925 presentFence1->signalForTest(52);
1926
1927 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001928 EXPECT_EQ(displayFrame0->getActuals().presentTime, 0);
1929
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001930 // case 2 - cpu time = 56 - 52 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001931 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001932 mFrameTimeline->setSfPresent(56, presentFence2, gpuFence2);
1933 auto displayFrame1 = getDisplayFrame(1);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001934 gpuFence2->signalForTest(76);
1935 presentFence2->signalForTest(90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001936
1937 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1938 // Fences have flushed for first displayFrame, so the present timestamps should be updated
1939 EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
1940 EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1941 EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Rachel Lee94917b32022-03-18 17:52:09 -07001942 EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00001943 EXPECT_EQ(displayFrame0->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001944
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001945 // case 3 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001946 mFrameTimeline->setSfWakeUp(sfToken3, 106, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001947 mFrameTimeline->setSfPresent(112, presentFence3, gpuFence3);
1948 auto displayFrame2 = getDisplayFrame(2);
1949 gpuFence3->signalForTest(116);
1950 presentFence3->signalForTest(120);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001951
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001952 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001953 // Fences have flushed for second displayFrame, so the present timestamps should be updated
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001954 EXPECT_EQ(displayFrame1->getActuals().presentTime, 90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001955 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1956 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1957 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00001958 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001959
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001960 // case 4 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001961 mFrameTimeline->setSfWakeUp(sfToken4, 120, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001962 mFrameTimeline->setSfPresent(140, presentFence4, gpuFence4);
1963 auto displayFrame3 = getDisplayFrame(3);
1964 gpuFence4->signalForTest(156);
1965 presentFence4->signalForTest(180);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001966
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001967 EXPECT_EQ(displayFrame3->getActuals().presentTime, 0);
1968 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1969 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1970 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1971 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1972 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00001973 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001974
1975 addEmptyDisplayFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001976
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001977 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1978 EXPECT_EQ(displayFrame3->getActuals().presentTime, 180);
1979 EXPECT_EQ(displayFrame3->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1980 EXPECT_EQ(displayFrame3->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1981 EXPECT_EQ(displayFrame3->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00001982 EXPECT_EQ(displayFrame3->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001983}
1984
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001985TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001986 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001987 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001988 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1989 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001990 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1991 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08001992 FrameTimelineInfo ftInfo;
1993 ftInfo.vsyncId = surfaceFrameToken1;
1994 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001995 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001996 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1997 sLayerNameOne, sLayerNameOne,
1998 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001999 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002000 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002001 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2002 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002003 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002004 auto displayFrame1 = getDisplayFrame(0);
2005 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2006 presentFence1->signalForTest(30);
2007
2008 // Fences for the first frame haven't been flushed yet, so it should be 0
2009 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2010 auto actuals1 = presentedSurfaceFrame1.getActuals();
2011 EXPECT_EQ(actuals1.presentTime, 0);
2012
2013 // Trigger a flush by finalizing the next DisplayFrame
2014 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002015 FrameTimelineInfo ftInfo2;
2016 ftInfo2.vsyncId = surfaceFrameToken2;
2017 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002018 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002019 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2020 sLayerNameOne, sLayerNameOne,
2021 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002022 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002023 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002024 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2025 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002026 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002027 auto displayFrame2 = getDisplayFrame(1);
2028 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2029
2030 // Fences for the first frame have flushed, so the present timestamps should be updated
2031 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
2032 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2033 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2034 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00002035 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002036
2037 actuals1 = presentedSurfaceFrame1.getActuals();
2038 EXPECT_EQ(actuals1.presentTime, 30);
2039 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2040 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2041 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00002042 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002043
2044 // Fences for the second frame haven't been flushed yet, so it should be 0
2045 presentFence2->signalForTest(65);
2046 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2047 auto actuals2 = presentedSurfaceFrame2.getActuals();
2048 EXPECT_EQ(actuals2.presentTime, 0);
2049
Alec Mouri363faf02021-01-29 16:34:55 -08002050 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
2051
2052 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002053 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
2054 sLayerNameOne, sGameMode,
2055 JankType::PredictionError, -3, 5,
2056 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08002057
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002058 addEmptyDisplayFrame();
2059
2060 // Fences for the second frame have flushed, so the present timestamps should be updated
2061 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
2062 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2063 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2064 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002065 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002066
2067 actuals2 = presentedSurfaceFrame2.getActuals();
2068 EXPECT_EQ(actuals2.presentTime, 65);
2069 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2070 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2071 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002072 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002073}
2074
2075TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08002076 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002077 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002078 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
2079 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002080 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
2081 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08002082 FrameTimelineInfo ftInfo;
2083 ftInfo.vsyncId = surfaceFrameToken1;
2084 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002085 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002086 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2087 sLayerNameOne, sLayerNameOne,
2088 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002089 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002090 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002091 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2092 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2093 mFrameTimeline->setSfPresent(26, presentFence1);
2094 auto displayFrame1 = getDisplayFrame(0);
2095 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2096 presentFence1->signalForTest(50);
2097
2098 // Fences for the first frame haven't been flushed yet, so it should be 0
2099 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2100 auto actuals1 = presentedSurfaceFrame1.getActuals();
2101 EXPECT_EQ(actuals1.presentTime, 0);
2102
2103 // Trigger a flush by finalizing the next DisplayFrame
2104 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002105 FrameTimelineInfo ftInfo2;
2106 ftInfo2.vsyncId = surfaceFrameToken2;
2107 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002108 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002109 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2110 sLayerNameOne, sLayerNameOne,
2111 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002112 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002113 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002114 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2115 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002116 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002117 auto displayFrame2 = getDisplayFrame(1);
2118 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2119
2120 // Fences for the first frame have flushed, so the present timestamps should be updated
2121 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
2122 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2123 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2124 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002125 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002126
2127 actuals1 = presentedSurfaceFrame1.getActuals();
2128 EXPECT_EQ(actuals1.presentTime, 50);
2129 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2130 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2131 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002132 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002133
2134 // Fences for the second frame haven't been flushed yet, so it should be 0
2135 presentFence2->signalForTest(86);
2136 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2137 auto actuals2 = presentedSurfaceFrame2.getActuals();
2138 EXPECT_EQ(actuals2.presentTime, 0);
2139
Alec Mouri363faf02021-01-29 16:34:55 -08002140 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
2141
2142 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002143 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
2144 sLayerNameOne, sGameMode,
2145 JankType::PredictionError, -3, 5,
2146 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08002147
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002148 addEmptyDisplayFrame();
2149
2150 // Fences for the second frame have flushed, so the present timestamps should be updated
2151 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
2152 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2153 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2154 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002155 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002156
2157 actuals2 = presentedSurfaceFrame2.getActuals();
2158 EXPECT_EQ(actuals2.presentTime, 86);
2159 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2160 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2161 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002162 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002163}
2164
2165TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08002166 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08002167
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002168 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002169 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002170 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -08002171 FrameTimelineInfo ftInfo;
2172 ftInfo.vsyncId = surfaceFrameToken1;
2173 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002174 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002175 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2176 sLayerNameOne, sLayerNameOne,
2177 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002178 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002179 mFrameTimeline->setSfWakeUp(sfToken1, 42, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002180 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2181 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2182 mFrameTimeline->setSfPresent(46, presentFence1);
2183 auto displayFrame1 = getDisplayFrame(0);
2184 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2185 presentFence1->signalForTest(50);
2186
2187 // Fences for the first frame haven't been flushed yet, so it should be 0
2188 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2189 auto actuals1 = presentedSurfaceFrame1.getActuals();
2190 EXPECT_EQ(actuals1.presentTime, 0);
2191
2192 addEmptyDisplayFrame();
2193
2194 // Fences for the first frame have flushed, so the present timestamps should be updated
2195 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
2196 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2197 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2198 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002199 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002200
2201 actuals1 = presentedSurfaceFrame1.getActuals();
2202 EXPECT_EQ(actuals1.presentTime, 50);
2203 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2204 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2205 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +00002206 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002207}
2208
2209TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002210 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as only
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002211 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002212 // jank to the SurfaceFrame along with AppDeadlineMissed.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002213
Alec Mouri363faf02021-01-29 16:34:55 -08002214 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002215 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002216 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
2217 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002218 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
2219 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
Huihong Luo3bdef862022-03-03 11:57:19 -08002220 FrameTimelineInfo ftInfo;
2221 ftInfo.vsyncId = surfaceFrameToken1;
2222 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002223 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002224 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2225 sLayerNameOne, sLayerNameOne,
2226 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002227 surfaceFrame1->setAcquireFenceTime(26);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002228 mFrameTimeline->setSfWakeUp(sfToken1, 32, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002229 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2230 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2231 mFrameTimeline->setSfPresent(36, presentFence1);
2232 auto displayFrame1 = getDisplayFrame(0);
2233 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2234 presentFence1->signalForTest(40);
2235
2236 // Fences for the first frame haven't been flushed yet, so it should be 0
2237 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2238 auto actuals1 = presentedSurfaceFrame1.getActuals();
2239 EXPECT_EQ(actuals1.presentTime, 0);
2240
2241 // Trigger a flush by finalizing the next DisplayFrame
2242 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002243 FrameTimelineInfo ftInfo2;
2244 ftInfo2.vsyncId = surfaceFrameToken2;
2245 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002246 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002247 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2248 sLayerNameOne, sLayerNameOne,
2249 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002250 surfaceFrame2->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002251 mFrameTimeline->setSfWakeUp(sfToken2, 43, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002252 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2253 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2254 mFrameTimeline->setSfPresent(56, presentFence2);
2255 auto displayFrame2 = getDisplayFrame(1);
2256 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2257
2258 // Fences for the first frame have flushed, so the present timestamps should be updated
2259 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
2260 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2261 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2262 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002263 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002264
2265 actuals1 = presentedSurfaceFrame1.getActuals();
2266 EXPECT_EQ(actuals1.presentTime, 40);
2267 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2268 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2269 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002270 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002271
2272 // Fences for the second frame haven't been flushed yet, so it should be 0
2273 presentFence2->signalForTest(60);
2274 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2275 auto actuals2 = presentedSurfaceFrame2.getActuals();
2276 EXPECT_EQ(actuals2.presentTime, 0);
2277
2278 addEmptyDisplayFrame();
2279
2280 // Fences for the second frame have flushed, so the present timestamps should be updated
2281 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
2282 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2283 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2284 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002285 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002286
2287 actuals2 = presentedSurfaceFrame2.getActuals();
2288 EXPECT_EQ(actuals2.presentTime, 60);
2289 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2290 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002291 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2292 JankType::SurfaceFlingerCpuDeadlineMissed | JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002293 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002294}
2295
2296TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002297 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08002298 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002299 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2300 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2301 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2302
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002303 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2304 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Huihong Luo3bdef862022-03-03 11:57:19 -08002305 FrameTimelineInfo ftInfo;
2306 ftInfo.vsyncId = surfaceFrameToken1;
2307 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002308 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002309 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2310 sLayerNameOne, sLayerNameOne,
2311 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002312 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002313 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002314 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2315 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2316 mFrameTimeline->setSfPresent(56, presentFence1);
2317 auto displayFrame1 = getDisplayFrame(0);
2318 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2319 presentFence1->signalForTest(60);
2320
2321 // Fences for the first frame haven't been flushed yet, so it should be 0
2322 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2323 auto actuals1 = presentedSurfaceFrame1.getActuals();
2324 EXPECT_EQ(actuals1.presentTime, 0);
2325
2326 // Trigger a flush by finalizing the next DisplayFrame
2327 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002328 FrameTimelineInfo ftInfo2;
2329 ftInfo2.vsyncId = surfaceFrameToken2;
2330 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002331 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002332 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2333 sLayerNameOne, sLayerNameOne,
2334 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002335 surfaceFrame2->setAcquireFenceTime(84);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002336 mFrameTimeline->setSfWakeUp(sfToken2, 112, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002337 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2338 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2339 mFrameTimeline->setSfPresent(116, presentFence2);
2340 auto displayFrame2 = getDisplayFrame(1);
2341 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2342 presentFence2->signalForTest(120);
2343
2344 // Fences for the first frame have flushed, so the present timestamps should be updated
2345 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2346 actuals1 = presentedSurfaceFrame1.getActuals();
2347 EXPECT_EQ(actuals1.endTime, 50);
2348 EXPECT_EQ(actuals1.presentTime, 60);
2349
2350 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2351 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2352 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002353 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002354
2355 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2356 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2357 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002358 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002359
2360 // Fences for the second frame haven't been flushed yet, so it should be 0
2361 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2362 auto actuals2 = presentedSurfaceFrame2.getActuals();
2363 EXPECT_EQ(actuals2.presentTime, 0);
2364
2365 addEmptyDisplayFrame();
2366
2367 // Fences for the second frame have flushed, so the present timestamps should be updated
2368 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
2369 actuals2 = presentedSurfaceFrame2.getActuals();
2370 EXPECT_EQ(actuals2.presentTime, 120);
2371
2372 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2373 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2374 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002375 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002376
2377 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2378 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2379 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2380 JankType::AppDeadlineMissed | JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00002381 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002382}
Alec Mouriadebf5c2021-01-05 12:57:36 -08002383
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002384TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
2385 // Layer specific increment
2386 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
2387 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2388 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2389 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2390
2391 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2392 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -08002393 FrameTimelineInfo ftInfo;
2394 ftInfo.vsyncId = surfaceFrameToken1;
2395 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002396 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002397 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2398 sLayerNameOne, sLayerNameOne,
2399 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002400 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002401 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002402 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2403 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2404 mFrameTimeline->setSfPresent(56, presentFence1);
2405 auto displayFrame1 = getDisplayFrame(0);
2406 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2407 presentFence1->signalForTest(60);
2408
2409 // Fences for the first frame haven't been flushed yet, so it should be 0
2410 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2411 auto actuals1 = presentedSurfaceFrame1.getActuals();
2412 EXPECT_EQ(actuals1.presentTime, 0);
2413
2414 // Trigger a flush by finalizing the next DisplayFrame
2415 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002416 FrameTimelineInfo ftInfo2;
2417 ftInfo2.vsyncId = surfaceFrameToken2;
2418 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002419 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002420 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2421 sLayerNameOne, sLayerNameOne,
2422 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002423 surfaceFrame2->setAcquireFenceTime(80);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002424 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002425 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
2426 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2427 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2428 mFrameTimeline->setSfPresent(86, presentFence2);
2429 auto displayFrame2 = getDisplayFrame(1);
2430 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2431 presentFence2->signalForTest(90);
2432
2433 // Fences for the first frame have flushed, so the present timestamps should be updated
2434 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2435 actuals1 = presentedSurfaceFrame1.getActuals();
2436 EXPECT_EQ(actuals1.endTime, 50);
2437 EXPECT_EQ(actuals1.presentTime, 60);
2438
2439 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2440 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2441 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002442 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002443
2444 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2445 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2446 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002447 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002448
2449 // Fences for the second frame haven't been flushed yet, so it should be 0
2450 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2451 auto actuals2 = presentedSurfaceFrame2.getActuals();
2452 EXPECT_EQ(actuals2.presentTime, 0);
2453
2454 addEmptyDisplayFrame();
2455
2456 // Fences for the second frame have flushed, so the present timestamps should be updated
2457 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2458 actuals2 = presentedSurfaceFrame2.getActuals();
2459 EXPECT_EQ(actuals2.presentTime, 90);
2460
2461 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2462 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2463 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002464 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002465
2466 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2467 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2468 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00002469 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002470}
2471
Rachel Lee94917b32022-03-18 17:52:09 -07002472TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent_GpuAndCpuMiss) {
2473 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2474 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2475 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2476 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2477 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2478
2479 // Case 1: cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002480 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Rachel Lee94917b32022-03-18 17:52:09 -07002481 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
2482 auto displayFrame = getDisplayFrame(0);
2483 gpuFence1->signalForTest(36);
2484 presentFence1->signalForTest(52);
2485
2486 // Fences haven't been flushed yet, so it should be 0
2487 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
2488
2489 addEmptyDisplayFrame();
2490 displayFrame = getDisplayFrame(0);
2491
2492 // Fences have flushed, so the present timestamps should be updated
2493 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
2494 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2495 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2496 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002497 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Full);
Rachel Lee94917b32022-03-18 17:52:09 -07002498
2499 // Case 2: No GPU fence so it will not use GPU composition.
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002500 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Rachel Lee94917b32022-03-18 17:52:09 -07002501 mFrameTimeline->setSfPresent(66, presentFence2);
2502 auto displayFrame2 = getDisplayFrame(2); // 2 because of previous empty frame
2503 presentFence2->signalForTest(90);
2504
2505 // Fences for the frame haven't been flushed yet, so it should be 0
2506 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2507
2508 addEmptyDisplayFrame();
2509
2510 // Fences have flushed, so the present timestamps should be updated
2511 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2512 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2513 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2514 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002515 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Rachel Lee94917b32022-03-18 17:52:09 -07002516}
2517
Ady Abrahamfcb16862022-10-10 14:35:21 -07002518TEST_F(FrameTimelineTest, jankClassification_presentFenceError) {
2519 auto erroneousPresentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2520 auto erroneousPresentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2521 auto validPresentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2522 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2523 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2524 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({72, 80, 80});
2525
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002526 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002527 mFrameTimeline->setSfPresent(26, erroneousPresentFence1);
2528
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002529 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002530 mFrameTimeline->setSfPresent(60, erroneousPresentFence2);
2531
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002532 mFrameTimeline->setSfWakeUp(sfToken3, 72, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002533 mFrameTimeline->setSfPresent(80, validPresentFence);
2534
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002535 erroneousPresentFence2->signalForTest(2);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002536 validPresentFence->signalForTest(80);
2537
2538 addEmptyDisplayFrame();
2539
2540 {
2541 auto displayFrame = getDisplayFrame(0);
2542 EXPECT_EQ(displayFrame->getActuals().presentTime, 26);
2543 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2544 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002545 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002546 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002547 }
2548 {
2549 auto displayFrame = getDisplayFrame(1);
2550 EXPECT_EQ(displayFrame->getActuals().presentTime, 60);
2551 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2552 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002553 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002554 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002555 }
2556 {
2557 auto displayFrame = getDisplayFrame(2);
2558 EXPECT_EQ(displayFrame->getActuals().presentTime, 80);
2559 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2560 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2561 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002562 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::None);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002563 }
2564}
2565
Alec Mouriadebf5c2021-01-05 12:57:36 -08002566TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
2567 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
2568}
2569
2570TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002571 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002572
2573 auto surfaceFrame1 =
2574 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002575 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002576 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002577 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2578 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2579 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2580 presentFence1->signalForTest(oneHundredMs);
2581 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2582
2583 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2584}
2585
2586TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002587 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2588 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002589 auto surfaceFrame1 =
2590 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002591 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002592 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002593 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2594 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2595 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2596 presentFence1->signalForTest(oneHundredMs);
2597 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2598
2599 auto surfaceFrame2 =
2600 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002601 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002602 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002603 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2604 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2605 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2606 presentFence2->signalForTest(twoHundredMs);
2607 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2608
2609 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
2610}
2611
2612TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002613 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2614 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002615 auto surfaceFrame1 =
2616 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002617 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002618 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002619 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2620 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2621 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2622 presentFence1->signalForTest(oneHundredMs);
2623 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2624
2625 auto surfaceFrame2 =
2626 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002627 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002628 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002629 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2630 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2631 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2632 presentFence2->signalForTest(twoHundredMs);
2633 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2634
2635 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
2636}
2637
2638TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002639 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2640 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002641 auto surfaceFrame1 =
2642 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002643 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002644 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002645 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2646 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2647 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2648 presentFence1->signalForTest(oneHundredMs);
2649 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2650
2651 auto surfaceFrame2 =
2652 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002653 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002654 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002655 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2656 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2657 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2658 presentFence2->signalForTest(twoHundredMs);
2659 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2660
2661 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2662}
2663
2664TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002665 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2666 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2667 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2668 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2669 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002670 auto surfaceFrame1 =
2671 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002672 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002673 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002674 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2675 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2676 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2677 presentFence1->signalForTest(oneHundredMs);
2678 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2679
2680 auto surfaceFrame2 =
2681 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002682 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002683 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002684 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2685 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2686 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2687 presentFence2->signalForTest(twoHundredMs);
2688 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2689
2690 auto surfaceFrame3 =
2691 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002692 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002693 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002694 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2695 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2696 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2697 presentFence3->signalForTest(threeHundredMs);
2698 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2699
2700 auto surfaceFrame4 =
2701 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002702 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002703 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002704 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2705 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2706 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2707 presentFence4->signalForTest(fiveHundredMs);
2708 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2709
2710 auto surfaceFrame5 =
2711 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002712 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002713 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002714 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2715 // Dropped frames will be excluded from fps computation
2716 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2717 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2718 presentFence5->signalForTest(sixHundredMs);
2719 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2720
2721 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2722}
2723
ramindaniea2bb822022-06-27 19:52:10 +00002724TEST_F(FrameTimelineTest, getMinTime) {
2725 // Use SurfaceFrame::getBaseTime to test the getMinTime.
2726 FrameTimelineInfo ftInfo;
2727
2728 // Valid prediction state test.
2729 ftInfo.vsyncId = 0L;
2730 mTokenManager->generateTokenForPredictions({10});
2731 auto surfaceFrame =
2732 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2733 sLayerNameOne, sLayerNameOne,
2734 /*isBuffer*/ true, sGameMode);
2735 ASSERT_EQ(surfaceFrame->getBaseTime(), 10);
2736
2737 // Test prediction state which is not valid.
2738 ftInfo.vsyncId = FrameTimelineInfo::INVALID_VSYNC_ID;
2739 surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2740 sLayerNameOne, sLayerNameOne,
2741 /*isBuffer*/ true, sGameMode);
2742 // Start time test.
2743 surfaceFrame->setActualStartTime(200);
2744 ASSERT_EQ(surfaceFrame->getBaseTime(), 200);
2745
2746 // End time test.
2747 surfaceFrame->setAcquireFenceTime(100);
2748 ASSERT_EQ(surfaceFrame->getBaseTime(), 100);
2749
2750 // Present time test.
2751 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2752 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2753 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2754 presentFence->signalForTest(std::chrono::nanoseconds(50ns).count());
2755 mFrameTimeline->setSfPresent(50, presentFence);
2756 ASSERT_EQ(surfaceFrame->getBaseTime(), 50);
2757}
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002758
2759TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingDisplayRate) {
2760 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2761 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2762 FrameTimelineInfo ftInfo;
2763 ftInfo.vsyncId = token1;
2764 ftInfo.inputEventId = sInputEventId;
2765 auto surfaceFrame =
2766 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2767 sLayerNameOne, sLayerNameOne,
2768 /*isBuffer*/ true, sGameMode);
2769
2770 mFrameTimeline->setSfWakeUp(token1, 20, RR_30, RR_11);
2771 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2772 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2773 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2774 mFrameTimeline->setSfPresent(50, presentFence1);
2775
2776 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 11);
2777}
2778
2779TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingAppFrameRate) {
2780 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2781 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2782 FrameTimelineInfo ftInfo;
2783 ftInfo.vsyncId = token1;
2784 ftInfo.inputEventId = sInputEventId;
2785 auto surfaceFrame =
2786 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2787 sLayerNameOne, sLayerNameOne,
2788 /*isBuffer*/ true, sGameMode);
2789 surfaceFrame->setRenderRate(RR_30);
2790 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
2791 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2792 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2793 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2794 mFrameTimeline->setSfPresent(50, presentFence1);
2795
2796 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 30);
2797}
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002798} // namespace android::frametimeline