blob: e96e0076b4c28a3710753c3ccef0c37747b1f043 [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
Vishnu Nairbd7d07e2024-07-08 13:37:11 -0700461TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceUnsignaled) {
462 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
463 "acquireFenceAfterQueue",
464 "acquireFenceAfterQueue",
465 /*isBuffer*/ true, sGameMode);
466 surfaceFrame->setActualQueueTime(123);
467 surfaceFrame->setAcquireFenceTime(Fence::SIGNAL_TIME_PENDING);
468 EXPECT_EQ(surfaceFrame->getActuals().endTime, 123);
469}
470
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700471TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000472 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
473 "acquireFenceAfterQueue",
474 "acquireFenceAfterQueue",
475 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700476 surfaceFrame->setActualQueueTime(456);
477 surfaceFrame->setAcquireFenceTime(123);
478 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
479}
480
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700481TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
482 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
483 presentFence->signalForTest(2);
484
485 // Size shouldn't exceed maxDisplayFrames - 64
486 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700487 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800488 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000489 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000490 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700491 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200492 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800493 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
494 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700495 mFrameTimeline->setSfPresent(27, presentFence);
496 }
497 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
498
499 // Increase the size to 256
500 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000501 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700502
503 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700504 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800505 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000506 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000507 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700508 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200509 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800510 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
511 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700512 mFrameTimeline->setSfPresent(27, presentFence);
513 }
514 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
515
516 // Shrink the size to 128
517 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000518 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700519
520 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700521 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800522 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000523 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000524 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700525 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200526 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800527 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
528 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700529 mFrameTimeline->setSfPresent(27, presentFence);
530 }
531 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
532}
Alec Mouri9a29e672020-09-14 12:39:14 -0700533
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000534TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200535 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000536
537 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
538 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
539 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800540 FrameTimelineInfo ftInfo;
541 ftInfo.vsyncId = surfaceFrameToken1;
542 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000543
544 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800545 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
546 sLayerNameOne, sLayerNameOne,
547 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200548 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000549 surfaceFrame1->setAcquireFenceTime(20);
550 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
551 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
552
553 mFrameTimeline->setSfPresent(59, presentFence1);
554 presentFence1->signalForTest(-1);
555 addEmptyDisplayFrame();
556
557 auto displayFrame0 = getDisplayFrame(0);
Ady Abrahamfcb16862022-10-10 14:35:21 -0700558 EXPECT_EQ(displayFrame0->getActuals().presentTime, 59);
Ady Abrahamb1e10d12023-03-13 15:23:54 -0700559 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +0000560 EXPECT_EQ(displayFrame0->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000561 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
562 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +0000563 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000564}
565
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800566// Tests related to TimeStats
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000567TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200568 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000569 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
570 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
571 int64_t surfaceFrameToken1 = -1;
572 int64_t sfToken1 = -1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800573 FrameTimelineInfo ftInfo;
574 ftInfo.vsyncId = surfaceFrameToken1;
575 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000576
577 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800578 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
579 sLayerNameOne, sLayerNameOne,
580 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200581 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000582 surfaceFrame1->setAcquireFenceTime(20);
583 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
584 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
585 presentFence1->signalForTest(70);
586
587 mFrameTimeline->setSfPresent(59, presentFence1);
588}
589
Alec Mouri9a29e672020-09-14 12:39:14 -0700590TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200591 Fps refreshRate = RR_11;
Alec Mouri9a29e672020-09-14 12:39:14 -0700592 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800593 incrementJankyFrames(
594 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000595 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000596 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800597 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700598 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000599 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
600 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800601 FrameTimelineInfo ftInfo;
602 ftInfo.vsyncId = surfaceFrameToken1;
603 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000604
Alec Mouri9a29e672020-09-14 12:39:14 -0700605 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800606 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
607 sLayerNameOne, sLayerNameOne,
608 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200609 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000610 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800611 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
612 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000613 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700614
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000615 mFrameTimeline->setSfPresent(62, presentFence1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700616}
617
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000618TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfGpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200619 Fps refreshRate = RR_11;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000620 EXPECT_CALL(*mTimeStats,
621 incrementJankyFrames(
622 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000623 sLayerNameOne, sGameMode,
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000624 JankType::SurfaceFlingerGpuDeadlineMissed, 4, 10,
625 0}));
626 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
627 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
628 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
629 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800630 FrameTimelineInfo ftInfo;
631 ftInfo.vsyncId = surfaceFrameToken1;
632 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000633
634 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800635 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
636 sLayerNameOne, sLayerNameOne,
637 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200638 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000639 surfaceFrame1->setAcquireFenceTime(20);
640 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
641 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
642 gpuFence1->signalForTest(64);
643 presentFence1->signalForTest(70);
644
645 mFrameTimeline->setSfPresent(59, presentFence1, gpuFence1);
646}
647
Alec Mouri9a29e672020-09-14 12:39:14 -0700648TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200649 Fps refreshRate = RR_30;
Alec Mouri9a29e672020-09-14 12:39:14 -0700650 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800651 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000652 sLayerNameOne, sGameMode,
653 JankType::DisplayHAL, -4, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800654
Alec Mouri9a29e672020-09-14 12:39:14 -0700655 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000656 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
657 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800658 FrameTimelineInfo ftInfo;
659 ftInfo.vsyncId = surfaceFrameToken1;
660 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000661
Alec Mouri9a29e672020-09-14 12:39:14 -0700662 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800663 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
664 sLayerNameOne, sLayerNameOne,
665 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200666 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800667 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000668 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800669 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000670 presentFence1->signalForTest(90);
671 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800672 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +0000673 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Alec Mouri9a29e672020-09-14 12:39:14 -0700674}
675
676TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700677 Fps refreshRate = 11_Hz;
Alec Mouri9a29e672020-09-14 12:39:14 -0700678 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000679 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000680 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000681 JankType::AppDeadlineMissed, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000682 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700683 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000684 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
685 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800686 FrameTimelineInfo ftInfo;
687 ftInfo.vsyncId = surfaceFrameToken1;
688 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000689
Alec Mouri9a29e672020-09-14 12:39:14 -0700690 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800691 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
692 sLayerNameOne, sLayerNameOne,
693 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000694 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200695 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700696
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800697 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
698 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000699 presentFence1->signalForTest(90);
700 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100701
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800702 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000703 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Partial);
Alec Mouri9a29e672020-09-14 12:39:14 -0700704}
705
Adithya Srinivasanead17162021-02-18 02:17:37 +0000706TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000707 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000708 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000709 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000710 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000711 JankType::SurfaceFlingerScheduling,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000712 -4, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000713 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000714 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
715 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800716 FrameTimelineInfo ftInfo;
717 ftInfo.vsyncId = surfaceFrameToken1;
718 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000719
Adithya Srinivasanead17162021-02-18 02:17:37 +0000720 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800721 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
722 sLayerNameOne, sLayerNameOne,
723 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000724 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200725 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000726
727 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
728 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000729 presentFence1->signalForTest(60);
730 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000731
732 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +0000733 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000734}
735
736TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000737 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000738 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000739 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000740 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000741 JankType::PredictionError, -4, 5,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000742 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000743 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000744 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
745 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800746 FrameTimelineInfo ftInfo;
747 ftInfo.vsyncId = surfaceFrameToken1;
748 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000749
Adithya Srinivasanead17162021-02-18 02:17:37 +0000750 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800751 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
752 sLayerNameOne, sLayerNameOne,
753 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000754 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200755 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000756
757 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
758 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000759 presentFence1->signalForTest(65);
760 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000761
762 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +0000763 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000764}
765
766TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000767 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000768 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000769 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000770 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000771 JankType::BufferStuffing, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000772 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000773 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000774 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
775 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800776 FrameTimelineInfo ftInfo;
777 ftInfo.vsyncId = surfaceFrameToken1;
778 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000779
Adithya Srinivasanead17162021-02-18 02:17:37 +0000780 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800781 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
782 sLayerNameOne, sLayerNameOne,
783 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000784 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200785 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000786
787 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000788 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000789 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000790 presentFence1->signalForTest(90);
791 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000792
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000793 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +0000794 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000795}
796
Alec Mouri363faf02021-01-29 16:34:55 -0800797TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200798 Fps refreshRate = RR_11;
799 Fps renderRate = RR_30;
Alec Mouri363faf02021-01-29 16:34:55 -0800800 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000801 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne,
802 sLayerNameOne, sGameMode,
803 JankType::AppDeadlineMissed, -4, 0,
804 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800805 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000806 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
807 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800808 FrameTimelineInfo ftInfo;
809 ftInfo.vsyncId = surfaceFrameToken1;
810 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000811
Alec Mouri363faf02021-01-29 16:34:55 -0800812 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800813 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
814 sLayerNameOne, sLayerNameOne,
815 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000816 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200817 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800818
819 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
820 surfaceFrame1->setRenderRate(renderRate);
821 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000822 presentFence1->signalForTest(90);
823 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800824
825 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000826 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Alec Mouri363faf02021-01-29 16:34:55 -0800827}
828
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000829TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200830 Fps refreshRate = RR_11;
831 Fps renderRate = RR_30;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000832
833 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000834 incrementJankyFrames(
835 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000836 sGameMode,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000837 JankType::Unknown | JankType::AppDeadlineMissed,
Adithya Srinivasande272452021-04-10 00:21:00 +0000838 0, 0, 25}));
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000839 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
840 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
841 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800842 FrameTimelineInfo ftInfo;
843 ftInfo.vsyncId = surfaceFrameToken1;
844 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000845
846 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800847 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
848 sLayerNameOne, sLayerNameOne,
849 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000850 surfaceFrame1->setAcquireFenceTime(45);
851 // Trigger a prediction expiry
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000852 flushTokens();
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200853 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000854
855 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
856 surfaceFrame1->setRenderRate(renderRate);
857 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
858 presentFence1->signalForTest(90);
859 mFrameTimeline->setSfPresent(86, presentFence1);
860
861 auto displayFrame = getDisplayFrame(0);
862 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +0000863 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000864 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
865 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
866 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
867
868 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000869 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000870 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000871}
872
Adithya Srinivasan01189672020-10-20 14:23:05 -0700873/*
874 * Tracing Tests
875 *
876 * Trace packets are flushed all the way only when the next packet is traced.
877 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
878 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
879 * will have additional empty frames created for this reason.
880 */
881TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
882 auto tracingSession = getTracingSessionForTest();
883 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700884 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800885 FrameTimelineInfo ftInfo;
886 ftInfo.vsyncId = token1;
887 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000888 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800889 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
890 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000891 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700892
893 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200894 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800895 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
896 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700897 mFrameTimeline->setSfPresent(25, presentFence1);
898 presentFence1->signalForTest(30);
899
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000900 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700901
902 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000903 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700904}
905
906TEST_F(FrameTimelineTest, tracing_sanityTest) {
907 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800908 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800909 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700910 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700911
912 tracingSession->StartBlocking();
913 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
914 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800915 FrameTimelineInfo ftInfo;
916 ftInfo.vsyncId = token1;
917 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000918 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800919 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
920 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000921 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700922
923 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200924 mFrameTimeline->setSfWakeUp(token2, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800925 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
926 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700927 mFrameTimeline->setSfPresent(25, presentFence1);
928 presentFence1->signalForTest(30);
929
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000930 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000931 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700932 tracingSession->StopBlocking();
933
934 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000935 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000936 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700937}
938
939TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
940 auto tracingSession = getTracingSessionForTest();
941 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700942
943 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700944
945 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200946 mFrameTimeline->setSfWakeUp(-1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700947 mFrameTimeline->setSfPresent(25, presentFence1);
948 presentFence1->signalForTest(30);
949
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000950 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000951 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700952 tracingSession->StopBlocking();
953
954 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000955 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700956}
957
958TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
959 auto tracingSession = getTracingSessionForTest();
960 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700961
962 tracingSession->StartBlocking();
963 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -0800964 auto surfaceFrame1 =
965 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000966 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000967 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700968
969 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200970 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800971 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
972 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700973 mFrameTimeline->setSfPresent(25, presentFence1);
974 presentFence1->signalForTest(30);
975
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000976 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000977 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700978 tracingSession->StopBlocking();
979
980 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000981 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
982 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000983 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700984}
985
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000986ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
987 pid_t pid) {
988 ProtoExpectedDisplayFrameStart proto;
989 proto.set_cookie(cookie);
990 proto.set_token(token);
991 proto.set_pid(pid);
992 return proto;
993}
994
995ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
996 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Ying Wei96eb5352023-11-21 17:37:21 +0000997 bool gpuComposition, ProtoJankType jankType, ProtoJankSeverityType jankSeverityType,
998 ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000999 ProtoActualDisplayFrameStart proto;
1000 proto.set_cookie(cookie);
1001 proto.set_token(token);
1002 proto.set_pid(pid);
1003 proto.set_present_type(presentType);
1004 proto.set_on_time_finish(onTimeFinish);
1005 proto.set_gpu_composition(gpuComposition);
1006 proto.set_jank_type(jankType);
Ying Wei96eb5352023-11-21 17:37:21 +00001007 proto.set_jank_severity_type(jankSeverityType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001008 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001009 return proto;
1010}
1011
1012ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
1013 int64_t displayFrameToken,
1014 pid_t pid,
1015 std::string layerName) {
1016 ProtoExpectedSurfaceFrameStart proto;
1017 proto.set_cookie(cookie);
1018 proto.set_token(token);
1019 proto.set_display_frame_token(displayFrameToken);
1020 proto.set_pid(pid);
1021 proto.set_layer_name(layerName);
1022 return proto;
1023}
1024
1025ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
1026 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
1027 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Ying Wei96eb5352023-11-21 17:37:21 +00001028 ProtoJankType jankType, ProtoJankSeverityType jankSeverityType,
1029 ProtoPredictionType predictionType, bool isBuffer) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001030 ProtoActualSurfaceFrameStart proto;
1031 proto.set_cookie(cookie);
1032 proto.set_token(token);
1033 proto.set_display_frame_token(displayFrameToken);
1034 proto.set_pid(pid);
1035 proto.set_layer_name(layerName);
1036 proto.set_present_type(presentType);
1037 proto.set_on_time_finish(onTimeFinish);
1038 proto.set_gpu_composition(gpuComposition);
1039 proto.set_jank_type(jankType);
Ying Wei96eb5352023-11-21 17:37:21 +00001040 proto.set_jank_severity_type(jankSeverityType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001041 proto.set_prediction_type(predictionType);
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001042 proto.set_is_buffer(isBuffer);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001043 return proto;
1044}
1045
1046ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
1047 ProtoFrameEnd proto;
1048 proto.set_cookie(cookie);
1049 return proto;
1050}
1051
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001052void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
1053 const ProtoExpectedDisplayFrameStart& source) {
1054 ASSERT_TRUE(received.has_cookie());
1055 EXPECT_EQ(received.cookie(), source.cookie());
1056
Adithya Srinivasan01189672020-10-20 14:23:05 -07001057 ASSERT_TRUE(received.has_token());
1058 EXPECT_EQ(received.token(), source.token());
1059
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001060 ASSERT_TRUE(received.has_pid());
1061 EXPECT_EQ(received.pid(), source.pid());
1062}
1063
1064void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
1065 const ProtoActualDisplayFrameStart& source) {
1066 ASSERT_TRUE(received.has_cookie());
1067 EXPECT_EQ(received.cookie(), source.cookie());
1068
1069 ASSERT_TRUE(received.has_token());
1070 EXPECT_EQ(received.token(), source.token());
1071
1072 ASSERT_TRUE(received.has_pid());
1073 EXPECT_EQ(received.pid(), source.pid());
1074
Adithya Srinivasan01189672020-10-20 14:23:05 -07001075 ASSERT_TRUE(received.has_present_type());
1076 EXPECT_EQ(received.present_type(), source.present_type());
1077 ASSERT_TRUE(received.has_on_time_finish());
1078 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1079 ASSERT_TRUE(received.has_gpu_composition());
1080 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1081 ASSERT_TRUE(received.has_jank_type());
1082 EXPECT_EQ(received.jank_type(), source.jank_type());
Ying Wei96eb5352023-11-21 17:37:21 +00001083 ASSERT_TRUE(received.has_jank_severity_type());
1084 EXPECT_EQ(received.jank_severity_type(), source.jank_severity_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001085 ASSERT_TRUE(received.has_prediction_type());
1086 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001087}
1088
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001089void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
1090 const ProtoExpectedSurfaceFrameStart& source) {
1091 ASSERT_TRUE(received.has_cookie());
1092 EXPECT_EQ(received.cookie(), source.cookie());
1093
Adithya Srinivasan01189672020-10-20 14:23:05 -07001094 ASSERT_TRUE(received.has_token());
1095 EXPECT_EQ(received.token(), source.token());
1096
1097 ASSERT_TRUE(received.has_display_frame_token());
1098 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1099
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001100 ASSERT_TRUE(received.has_pid());
1101 EXPECT_EQ(received.pid(), source.pid());
1102
1103 ASSERT_TRUE(received.has_layer_name());
1104 EXPECT_EQ(received.layer_name(), source.layer_name());
1105}
1106
1107void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
1108 const ProtoActualSurfaceFrameStart& source) {
1109 ASSERT_TRUE(received.has_cookie());
1110 EXPECT_EQ(received.cookie(), source.cookie());
1111
1112 ASSERT_TRUE(received.has_token());
1113 EXPECT_EQ(received.token(), source.token());
1114
1115 ASSERT_TRUE(received.has_display_frame_token());
1116 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1117
1118 ASSERT_TRUE(received.has_pid());
1119 EXPECT_EQ(received.pid(), source.pid());
1120
1121 ASSERT_TRUE(received.has_layer_name());
1122 EXPECT_EQ(received.layer_name(), source.layer_name());
1123
Adithya Srinivasan01189672020-10-20 14:23:05 -07001124 ASSERT_TRUE(received.has_present_type());
1125 EXPECT_EQ(received.present_type(), source.present_type());
1126 ASSERT_TRUE(received.has_on_time_finish());
1127 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1128 ASSERT_TRUE(received.has_gpu_composition());
1129 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1130 ASSERT_TRUE(received.has_jank_type());
1131 EXPECT_EQ(received.jank_type(), source.jank_type());
Ying Wei96eb5352023-11-21 17:37:21 +00001132 ASSERT_TRUE(received.has_jank_severity_type());
1133 EXPECT_EQ(received.jank_severity_type(), source.jank_severity_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001134 ASSERT_TRUE(received.has_prediction_type());
1135 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001136 ASSERT_TRUE(received.has_is_buffer());
1137 EXPECT_EQ(received.is_buffer(), source.is_buffer());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001138}
Adithya Srinivasan01189672020-10-20 14:23:05 -07001139
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001140void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
1141 ASSERT_TRUE(received.has_cookie());
1142 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001143}
1144
Sally Qi2269a692024-05-17 18:02:28 -07001145TEST_F(FrameTimelineTest, traceDisplayFrameNoSkipped) {
1146 // setup 2 display frames
1147 // DF 1: [22, 30] -> [0, 11]
1148 // DF 2: [82, 90] -> SF [5, 16]
1149 auto tracingSession = getTracingSessionForTest();
1150 tracingSession->StartBlocking();
1151 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1152 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 100});
1153 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({0, 11, 25});
1154 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1155 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1156
1157 int64_t traceCookie = snoopCurrentTraceCookie();
1158
1159 // set up 1st display frame
1160 FrameTimelineInfo ftInfo1;
1161 ftInfo1.vsyncId = surfaceFrameToken1;
1162 ftInfo1.inputEventId = sInputEventId;
1163 auto surfaceFrame1 =
1164 mFrameTimeline->createSurfaceFrameForToken(ftInfo1, sPidOne, sUidOne, sLayerIdOne,
1165 sLayerNameOne, sLayerNameOne,
1166 /*isBuffer*/ true, sGameMode);
1167 surfaceFrame1->setAcquireFenceTime(11);
1168 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_30);
1169 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1170 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1171 mFrameTimeline->setSfPresent(30, presentFence1);
1172 presentFence1->signalForTest(40);
1173
1174 // Trigger a flush by finalizing the next DisplayFrame
1175 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1176 FrameTimelineInfo ftInfo2;
1177 ftInfo2.vsyncId = surfaceFrameToken2;
1178 ftInfo2.inputEventId = sInputEventId;
1179 auto surfaceFrame2 =
1180 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1181 sLayerNameOne, sLayerNameOne,
1182 /*isBuffer*/ true, sGameMode);
1183
1184 // set up 2nd display frame
1185 surfaceFrame2->setAcquireFenceTime(16);
1186 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_11, RR_30);
1187 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1188 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1189 mFrameTimeline->setSfPresent(90, presentFence2);
1190 presentFence2->signalForTest(100);
1191
1192 // the token of skipped Display Frame
1193 auto protoSkippedActualDisplayFrameStart =
1194 createProtoActualDisplayFrameStart(traceCookie + 9, 0, kSurfaceFlingerPid,
1195 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1196 FrameTimelineEvent::JANK_DROPPED,
1197 FrameTimelineEvent::SEVERITY_NONE,
1198 FrameTimelineEvent::PREDICTION_VALID);
1199 auto protoSkippedActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 9);
1200
1201 // Trigger a flush by finalizing the next DisplayFrame
1202 addEmptyDisplayFrame();
1203 flushTrace();
1204 tracingSession->StopBlocking();
1205
1206 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1207 // 8 Valid Display Frames + 8 Valid Surface Frames + no Skipped Display Frames
1208 EXPECT_EQ(packets.size(), 16u);
1209}
1210
Sally Qiaa107742023-09-29 14:53:14 -07001211TEST_F(FrameTimelineTest, traceDisplayFrameSkipped) {
Sally Qif5721252023-11-17 11:14:53 -08001212 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::add_sf_skipped_frames_to_trace,
1213 true);
1214
Sally Qiaa107742023-09-29 14:53:14 -07001215 // setup 2 display frames
1216 // DF 1: [22,40] -> [5, 40]
1217 // DF : [36, 70] (Skipped one, added by the trace)
1218 // DF 2: [82, 100] -> SF [25, 70]
1219 auto tracingSession = getTracingSessionForTest();
1220 tracingSession->StartBlocking();
1221 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1222 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 100});
1223 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1224 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1225 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1226
1227 int64_t traceCookie = snoopCurrentTraceCookie();
1228
1229 // set up 1st display frame
1230 FrameTimelineInfo ftInfo1;
1231 ftInfo1.vsyncId = surfaceFrameToken1;
1232 ftInfo1.inputEventId = sInputEventId;
1233 auto surfaceFrame1 =
1234 mFrameTimeline->createSurfaceFrameForToken(ftInfo1, sPidOne, sUidOne, sLayerIdOne,
1235 sLayerNameOne, sLayerNameOne,
1236 /*isBuffer*/ true, sGameMode);
1237 surfaceFrame1->setAcquireFenceTime(16);
1238 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_30);
1239 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1240 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1241 mFrameTimeline->setSfPresent(30, presentFence1);
1242 presentFence1->signalForTest(40);
1243
1244 // Trigger a flush by finalizing the next DisplayFrame
1245 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1246 FrameTimelineInfo ftInfo2;
1247 ftInfo2.vsyncId = surfaceFrameToken2;
1248 ftInfo2.inputEventId = sInputEventId;
1249 auto surfaceFrame2 =
1250 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1251 sLayerNameOne, sLayerNameOne,
1252 /*isBuffer*/ true, sGameMode);
1253
1254 // set up 2nd display frame
1255 surfaceFrame2->setAcquireFenceTime(36);
1256 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_11, RR_30);
1257 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1258 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1259 mFrameTimeline->setSfPresent(90, presentFence2);
1260 presentFence2->signalForTest(100);
1261
1262 // the token of skipped Display Frame
1263 auto protoSkippedActualDisplayFrameStart =
1264 createProtoActualDisplayFrameStart(traceCookie + 9, 0, kSurfaceFlingerPid,
1265 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1266 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001267 FrameTimelineEvent::SEVERITY_NONE,
Sally Qiaa107742023-09-29 14:53:14 -07001268 FrameTimelineEvent::PREDICTION_VALID);
1269 auto protoSkippedActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 9);
1270
1271 // Trigger a flush by finalizing the next DisplayFrame
1272 addEmptyDisplayFrame();
1273 flushTrace();
1274 tracingSession->StopBlocking();
1275
1276 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1277 // 8 Valid Display Frames + 8 Valid Surface Frames + 2 Skipped Display Frames
1278 EXPECT_EQ(packets.size(), 18u);
1279
1280 // Packet - 16: Actual skipped Display Frame Start
1281 // the timestamp should be equal to the 2nd expected surface frame's end time
1282 const auto& packet16 = packets[16];
1283 ASSERT_TRUE(packet16.has_timestamp());
1284 EXPECT_EQ(packet16.timestamp(), 36u);
1285 ASSERT_TRUE(packet16.has_frame_timeline_event());
1286
1287 const auto& event16 = packet16.frame_timeline_event();
1288 const auto& actualSkippedDisplayFrameStart = event16.actual_display_frame_start();
1289 validateTraceEvent(actualSkippedDisplayFrameStart, protoSkippedActualDisplayFrameStart);
1290
1291 // Packet - 17: Actual skipped Display Frame End
1292 // the timestamp should be equal to the 2nd expected surface frame's present time
1293 const auto& packet17 = packets[17];
1294 ASSERT_TRUE(packet17.has_timestamp());
1295 EXPECT_EQ(packet17.timestamp(), 70u);
1296 ASSERT_TRUE(packet17.has_frame_timeline_event());
1297
1298 const auto& event17 = packet17.frame_timeline_event();
1299 const auto& actualSkippedDisplayFrameEnd = event17.frame_end();
1300 validateTraceEvent(actualSkippedDisplayFrameEnd, protoSkippedActualDisplayFrameEnd);
1301}
1302
Adithya Srinivasan01189672020-10-20 14:23:05 -07001303TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
1304 auto tracingSession = getTracingSessionForTest();
1305 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001306
1307 tracingSession->StartBlocking();
Ady Abraham57a8ab42023-01-26 15:28:19 -08001308
1309 // Add an empty surface frame so that display frame would get traced.
1310 addEmptySurfaceFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001311 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001312
1313 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001314 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001315 mFrameTimeline->setSfPresent(26, presentFence1);
1316 presentFence1->signalForTest(31);
1317
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001318 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001319 auto protoExpectedDisplayFrameStart =
1320 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1321 kSurfaceFlingerPid);
1322 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1323 auto protoActualDisplayFrameStart =
1324 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
1325 kSurfaceFlingerPid,
1326 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001327 FrameTimelineEvent::JANK_NONE,
Ying Wei96eb5352023-11-21 17:37:21 +00001328 FrameTimelineEvent::SEVERITY_NONE,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001329 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001330 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001331
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001332 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001333 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001334 tracingSession->StopBlocking();
1335
1336 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001337 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001338
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001339 // Packet - 0 : ExpectedDisplayFrameStart
1340 const auto& packet0 = packets[0];
1341 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001342 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001343 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001344
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001345 const auto& event0 = packet0.frame_timeline_event();
1346 ASSERT_TRUE(event0.has_expected_display_frame_start());
1347 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
1348 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
1349
1350 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
1351 const auto& packet1 = packets[1];
1352 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001353 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001354 ASSERT_TRUE(packet1.has_frame_timeline_event());
1355
1356 const auto& event1 = packet1.frame_timeline_event();
1357 ASSERT_TRUE(event1.has_frame_end());
1358 const auto& expectedDisplayFrameEnd = event1.frame_end();
1359 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
1360
1361 // Packet - 2 : ActualDisplayFrameStart
1362 const auto& packet2 = packets[2];
1363 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001364 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001365 ASSERT_TRUE(packet2.has_frame_timeline_event());
1366
1367 const auto& event2 = packet2.frame_timeline_event();
1368 ASSERT_TRUE(event2.has_actual_display_frame_start());
1369 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1370 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1371
1372 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1373 const auto& packet3 = packets[3];
1374 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001375 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001376 ASSERT_TRUE(packet3.has_frame_timeline_event());
1377
1378 const auto& event3 = packet3.frame_timeline_event();
1379 ASSERT_TRUE(event3.has_frame_end());
1380 const auto& actualDisplayFrameEnd = event3.frame_end();
1381 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001382}
1383
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001384TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1385 auto tracingSession = getTracingSessionForTest();
1386 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1387
1388 tracingSession->StartBlocking();
1389 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1390 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001391 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001392
Ady Abraham57a8ab42023-01-26 15:28:19 -08001393 // Add an empty surface frame so that display frame would get traced.
1394 addEmptySurfaceFrame();
1395
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001396 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001397 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001398 mFrameTimeline->setSfPresent(26, presentFence1);
1399 presentFence1->signalForTest(31);
1400
1401 int64_t traceCookie = snoopCurrentTraceCookie();
1402
1403 auto protoActualDisplayFrameStart =
1404 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1405 kSurfaceFlingerPid,
1406 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001407 false, FrameTimelineEvent::JANK_UNKNOWN,
Ying Wei96eb5352023-11-21 17:37:21 +00001408 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001409 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001410 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1411
1412 addEmptyDisplayFrame();
1413 flushTrace();
1414 tracingSession->StopBlocking();
1415
1416 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1417 // Only actual timeline packets should be in the trace
1418 EXPECT_EQ(packets.size(), 2u);
1419
1420 // Packet - 0 : ActualDisplayFrameStart
1421 const auto& packet0 = packets[0];
1422 ASSERT_TRUE(packet0.has_timestamp());
1423 EXPECT_EQ(packet0.timestamp(), 20u);
1424 ASSERT_TRUE(packet0.has_frame_timeline_event());
1425
1426 const auto& event0 = packet0.frame_timeline_event();
1427 ASSERT_TRUE(event0.has_actual_display_frame_start());
1428 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1429 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1430
1431 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1432 const auto& packet1 = packets[1];
1433 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001434 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001435 ASSERT_TRUE(packet1.has_frame_timeline_event());
1436
1437 const auto& event1 = packet1.frame_timeline_event();
1438 ASSERT_TRUE(event1.has_frame_end());
1439 const auto& actualDisplayFrameEnd = event1.frame_end();
1440 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1441}
1442
Adithya Srinivasan01189672020-10-20 14:23:05 -07001443TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1444 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001445 // Layer specific increment
Edgar Arriaga631e4252023-03-02 02:11:24 +00001446 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001447 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1448 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1449
1450 tracingSession->StartBlocking();
1451 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1452 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001453
Huihong Luo3bdef862022-03-03 11:57:19 -08001454 FrameTimelineInfo ftInfo;
1455 ftInfo.vsyncId = surfaceFrameToken;
1456 ftInfo.inputEventId = sInputEventId;
1457
Adithya Srinivasan01189672020-10-20 14:23:05 -07001458 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001459 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1460 sLayerNameOne, sLayerNameOne,
1461 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001462 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001463 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1464 sLayerNameOne, sLayerNameOne,
1465 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001466 surfaceFrame1->setActualQueueTime(10);
1467 surfaceFrame1->setDropTime(15);
1468
1469 surfaceFrame2->setActualQueueTime(15);
1470 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001471
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001472 // First 2 cookies will be used by the DisplayFrame
1473 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1474
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001475 auto protoDroppedSurfaceFrameExpectedStart =
1476 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1477 displayFrameToken1, sPidOne, sLayerNameOne);
1478 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1479 auto protoDroppedSurfaceFrameActualStart =
1480 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1481 displayFrameToken1, sPidOne, sLayerNameOne,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001482 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1483 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001484 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001485 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001486 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001487
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001488 auto protoPresentedSurfaceFrameExpectedStart =
1489 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1490 displayFrameToken1, sPidOne, sLayerNameOne);
1491 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1492 auto protoPresentedSurfaceFrameActualStart =
1493 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1494 displayFrameToken1, sPidOne, sLayerNameOne,
1495 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001496 FrameTimelineEvent::JANK_NONE,
Ying Wei96eb5352023-11-21 17:37:21 +00001497 FrameTimelineEvent::SEVERITY_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001498 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001499 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001500
1501 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001502 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001503 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1504 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001505 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001506 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001507 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001508 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001509
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001510 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001511 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001512 tracingSession->StopBlocking();
1513
1514 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001515 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1516 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001517
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001518 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001519 const auto& packet4 = packets[4];
1520 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001521 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001522 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001523
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001524 const auto& event4 = packet4.frame_timeline_event();
1525 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001526 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1527 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001528
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001529 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001530 const auto& packet5 = packets[5];
1531 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001532 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001533 ASSERT_TRUE(packet5.has_frame_timeline_event());
1534
1535 const auto& event5 = packet5.frame_timeline_event();
1536 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001537 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1538 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001539
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001540 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001541 const auto& packet6 = packets[6];
1542 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001543 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001544 ASSERT_TRUE(packet6.has_frame_timeline_event());
1545
1546 const auto& event6 = packet6.frame_timeline_event();
1547 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001548 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1549 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001550
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001551 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001552 const auto& packet7 = packets[7];
1553 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001554 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001555 ASSERT_TRUE(packet7.has_frame_timeline_event());
1556
1557 const auto& event7 = packet7.frame_timeline_event();
1558 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001559 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1560 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1561
1562 // Packet - 8 : ExpectedSurfaceFrameStart2
1563 const auto& packet8 = packets[8];
1564 ASSERT_TRUE(packet8.has_timestamp());
1565 EXPECT_EQ(packet8.timestamp(), 10u);
1566 ASSERT_TRUE(packet8.has_frame_timeline_event());
1567
1568 const auto& event8 = packet8.frame_timeline_event();
1569 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1570 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1571 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1572
1573 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1574 const auto& packet9 = packets[9];
1575 ASSERT_TRUE(packet9.has_timestamp());
1576 EXPECT_EQ(packet9.timestamp(), 25u);
1577 ASSERT_TRUE(packet9.has_frame_timeline_event());
1578
1579 const auto& event9 = packet9.frame_timeline_event();
1580 ASSERT_TRUE(event9.has_frame_end());
1581 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1582 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1583
1584 // Packet - 10 : ActualSurfaceFrameStart2
1585 const auto& packet10 = packets[10];
1586 ASSERT_TRUE(packet10.has_timestamp());
1587 EXPECT_EQ(packet10.timestamp(), 10u);
1588 ASSERT_TRUE(packet10.has_frame_timeline_event());
1589
1590 const auto& event10 = packet10.frame_timeline_event();
1591 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1592 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1593 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1594
1595 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1596 const auto& packet11 = packets[11];
1597 ASSERT_TRUE(packet11.has_timestamp());
1598 EXPECT_EQ(packet11.timestamp(), 20u);
1599 ASSERT_TRUE(packet11.has_frame_timeline_event());
1600
1601 const auto& event11 = packet11.frame_timeline_event();
1602 ASSERT_TRUE(event11.has_frame_end());
1603 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1604 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1605}
1606
Ady Abrahame43ff722022-02-15 14:44:25 -08001607TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredIsAppMissedDeadline) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001608 auto tracingSession = getTracingSessionForTest();
1609 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1610
1611 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001612 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1613 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1614 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001615 int64_t surfaceFrameToken =
1616 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1617
1618 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001619 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001620 FrameTimelineInfo ftInfo;
1621 ftInfo.vsyncId = surfaceFrameToken;
1622 ftInfo.inputEventId = 0;
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001623 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001624 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1625 sLayerNameOne, sLayerNameOne,
1626 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001627 surfaceFrame1->setActualQueueTime(appEndTime);
1628 surfaceFrame1->setAcquireFenceTime(appEndTime);
1629
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001630 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1631 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1632 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001633 int64_t displayFrameToken =
1634 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1635
1636 // First 2 cookies will be used by the DisplayFrame
1637 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1638
1639 auto protoActualSurfaceFrameStart =
1640 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1641 displayFrameToken, sPidOne, sLayerNameOne,
1642 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Ady Abrahame43ff722022-02-15 14:44:25 -08001643 false, FrameTimelineEvent::JANK_APP_DEADLINE_MISSED,
Ying Wei96eb5352023-11-21 17:37:21 +00001644 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001645 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001646 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1647
1648 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001649 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001650 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1651 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1652 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1653 presentFence1->signalForTest(sfPresentTime);
1654
1655 addEmptyDisplayFrame();
1656 flushTrace();
1657 tracingSession->StopBlocking();
1658
1659 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1660 // Display Frame 4 packets + SurfaceFrame 2 packets
1661 ASSERT_EQ(packets.size(), 6u);
1662
1663 // Packet - 4 : ActualSurfaceFrameStart
1664 const auto& packet4 = packets[4];
1665 ASSERT_TRUE(packet4.has_timestamp());
1666 EXPECT_EQ(packet4.timestamp(),
1667 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1668 ASSERT_TRUE(packet4.has_frame_timeline_event());
1669
1670 const auto& event4 = packet4.frame_timeline_event();
1671 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1672 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1673 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1674
1675 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1676 const auto& packet5 = packets[5];
1677 ASSERT_TRUE(packet5.has_timestamp());
1678 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1679 ASSERT_TRUE(packet5.has_frame_timeline_event());
1680
1681 const auto& event5 = packet5.frame_timeline_event();
1682 ASSERT_TRUE(event5.has_frame_end());
1683 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001684 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001685}
1686
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001687TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDroppedFramesTracedProperly) {
1688 auto tracingSession = getTracingSessionForTest();
1689 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1690
1691 tracingSession->StartBlocking();
1692 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1693 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1694 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
1695 int64_t surfaceFrameToken =
1696 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1697
1698 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001699 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001700 FrameTimelineInfo ftInfo;
1701 ftInfo.vsyncId = surfaceFrameToken;
1702 ftInfo.inputEventId = 0;
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001703 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001704 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1705 sLayerNameOne, sLayerNameOne,
1706 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001707
1708 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(22ms).count();
1709 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1710 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
1711 int64_t displayFrameToken =
1712 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1713
1714 // First 2 cookies will be used by the DisplayFrame
1715 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1716
1717 auto protoActualSurfaceFrameStart =
1718 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1719 displayFrameToken, sPidOne, sLayerNameOne,
1720 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001721 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001722 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001723 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001724 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1725
1726 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001727 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001728 surfaceFrame1->setDropTime(sfStartTime);
1729 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1730 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1731 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1732 presentFence1->signalForTest(sfPresentTime);
1733
1734 addEmptyDisplayFrame();
1735 flushTrace();
1736 tracingSession->StopBlocking();
1737
1738 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1739 // Display Frame 4 packets + SurfaceFrame 2 packets
1740 ASSERT_EQ(packets.size(), 6u);
1741
1742 // Packet - 4 : ActualSurfaceFrameStart
1743 const auto& packet4 = packets[4];
1744 ASSERT_TRUE(packet4.has_timestamp());
1745 EXPECT_EQ(packet4.timestamp(),
1746 static_cast<uint64_t>(sfStartTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1747 ASSERT_TRUE(packet4.has_frame_timeline_event());
1748
1749 const auto& event4 = packet4.frame_timeline_event();
1750 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1751 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1752 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1753
1754 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1755 const auto& packet5 = packets[5];
1756 ASSERT_TRUE(packet5.has_timestamp());
1757 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(sfStartTime));
1758 ASSERT_TRUE(packet5.has_frame_timeline_event());
1759
1760 const auto& event5 = packet5.frame_timeline_event();
1761 ASSERT_TRUE(event5.has_frame_end());
1762 const auto& actualSurfaceFrameEnd = event5.frame_end();
1763 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
1764}
1765
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001766// Tests for Jank classification
1767TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001768 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001769 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001770 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1771 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001772 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -08001773 FrameTimelineInfo ftInfo;
1774 ftInfo.vsyncId = surfaceFrameToken;
1775 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001776 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -08001777 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1778 sLayerNameOne, sLayerNameOne,
1779 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001780 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001781 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1782 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1783 mFrameTimeline->setSfPresent(26, presentFence1);
1784 auto displayFrame = getDisplayFrame(0);
1785 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1786 presentFence1->signalForTest(29);
1787
1788 // Fences haven't been flushed yet, so it should be 0
1789 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1790 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1791
1792 addEmptyDisplayFrame();
1793 displayFrame = getDisplayFrame(0);
1794
1795 // Fences have flushed, so the present timestamps should be updated
1796 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1797 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1798 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1799 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1800 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00001801 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001802}
1803
1804TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001805 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001806 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001807 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1808 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001809 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001810 mFrameTimeline->setSfPresent(26, presentFence1);
1811 auto displayFrame = getDisplayFrame(0);
1812 presentFence1->signalForTest(30);
1813
1814 // Fences for the first frame haven't been flushed yet, so it should be 0
1815 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1816
1817 // Trigger a flush by finalizing the next DisplayFrame
1818 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001819 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001820 mFrameTimeline->setSfPresent(56, presentFence2);
1821 displayFrame = getDisplayFrame(0);
1822
1823 // Fences for the first frame have flushed, so the present timestamps should be updated
1824 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1825 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1826 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1827 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00001828 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001829
1830 // Fences for the second frame haven't been flushed yet, so it should be 0
1831 auto displayFrame2 = getDisplayFrame(1);
1832 presentFence2->signalForTest(65);
1833 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001834 addEmptyDisplayFrame();
1835 displayFrame2 = getDisplayFrame(1);
1836
1837 // Fences for the second frame have flushed, so the present timestamps should be updated
1838 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1839 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1840 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1841 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00001842 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001843}
1844
1845TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001846 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001847 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001848 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1849 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001850 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001851 mFrameTimeline->setSfPresent(26, presentFence1);
1852 auto displayFrame = getDisplayFrame(0);
1853 presentFence1->signalForTest(50);
1854
1855 // Fences for the first frame haven't been flushed yet, so it should be 0
1856 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1857
1858 // Trigger a flush by finalizing the next DisplayFrame
1859 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001860 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001861 mFrameTimeline->setSfPresent(56, presentFence2);
1862 displayFrame = getDisplayFrame(0);
1863
1864 // Fences for the first frame have flushed, so the present timestamps should be updated
1865 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1866 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1867 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1868 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00001869 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001870
1871 // Fences for the second frame haven't been flushed yet, so it should be 0
1872 auto displayFrame2 = getDisplayFrame(1);
1873 presentFence2->signalForTest(75);
1874 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1875
1876 addEmptyDisplayFrame();
1877 displayFrame2 = getDisplayFrame(1);
1878
1879 // Fences for the second frame have flushed, so the present timestamps should be updated
1880 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1881 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1882 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1883 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00001884 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001885}
1886
1887TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001888 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1889 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001890 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001891
1892 mFrameTimeline->setSfPresent(22, presentFence1);
1893 auto displayFrame = getDisplayFrame(0);
1894 presentFence1->signalForTest(28);
1895
1896 // Fences haven't been flushed yet, so it should be 0
1897 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1898
1899 addEmptyDisplayFrame();
1900 displayFrame = getDisplayFrame(0);
1901
1902 // Fences have flushed, so the present timestamps should be updated
1903 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1904 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1905 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1906 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00001907 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001908}
1909
1910TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001911 /*
1912 * Case 1 - cpu time > vsync period but combined time > deadline > deadline -> cpudeadlinemissed
1913 * Case 2 - cpu time < vsync period but combined time > deadline -> gpudeadlinemissed
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001914 * Case 3 - previous frame ran longer -> sf_stuffing
1915 * Case 4 - Long cpu under SF stuffing -> cpudeadlinemissed
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001916 */
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001917 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001918 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001919 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1920 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001921 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1922 auto gpuFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001923 auto gpuFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1924 auto gpuFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001925 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001926 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001927 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1928 int64_t sfToken4 = mTokenManager->generateTokenForPredictions({112, 120, 120});
1929
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001930 // case 1 - cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001931 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001932 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
1933 auto displayFrame0 = getDisplayFrame(0);
1934 gpuFence1->signalForTest(36);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001935 presentFence1->signalForTest(52);
1936
1937 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001938 EXPECT_EQ(displayFrame0->getActuals().presentTime, 0);
1939
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001940 // case 2 - cpu time = 56 - 52 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001941 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001942 mFrameTimeline->setSfPresent(56, presentFence2, gpuFence2);
1943 auto displayFrame1 = getDisplayFrame(1);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001944 gpuFence2->signalForTest(76);
1945 presentFence2->signalForTest(90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001946
1947 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1948 // Fences have flushed for first displayFrame, so the present timestamps should be updated
1949 EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
1950 EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1951 EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Rachel Lee94917b32022-03-18 17:52:09 -07001952 EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00001953 EXPECT_EQ(displayFrame0->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001954
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001955 // case 3 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001956 mFrameTimeline->setSfWakeUp(sfToken3, 106, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001957 mFrameTimeline->setSfPresent(112, presentFence3, gpuFence3);
1958 auto displayFrame2 = getDisplayFrame(2);
1959 gpuFence3->signalForTest(116);
1960 presentFence3->signalForTest(120);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001961
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001962 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001963 // Fences have flushed for second displayFrame, so the present timestamps should be updated
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001964 EXPECT_EQ(displayFrame1->getActuals().presentTime, 90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001965 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1966 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1967 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00001968 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001969
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001970 // case 4 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001971 mFrameTimeline->setSfWakeUp(sfToken4, 120, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001972 mFrameTimeline->setSfPresent(140, presentFence4, gpuFence4);
1973 auto displayFrame3 = getDisplayFrame(3);
1974 gpuFence4->signalForTest(156);
1975 presentFence4->signalForTest(180);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001976
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001977 EXPECT_EQ(displayFrame3->getActuals().presentTime, 0);
1978 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1979 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1980 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1981 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1982 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00001983 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001984
1985 addEmptyDisplayFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001986
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001987 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1988 EXPECT_EQ(displayFrame3->getActuals().presentTime, 180);
1989 EXPECT_EQ(displayFrame3->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1990 EXPECT_EQ(displayFrame3->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1991 EXPECT_EQ(displayFrame3->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00001992 EXPECT_EQ(displayFrame3->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001993}
1994
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001995TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001996 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001997 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001998 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1999 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002000 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
2001 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08002002 FrameTimelineInfo ftInfo;
2003 ftInfo.vsyncId = surfaceFrameToken1;
2004 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002005 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002006 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2007 sLayerNameOne, sLayerNameOne,
2008 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002009 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002010 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002011 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2012 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002013 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002014 auto displayFrame1 = getDisplayFrame(0);
2015 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2016 presentFence1->signalForTest(30);
2017
2018 // Fences for the first frame haven't been flushed yet, so it should be 0
2019 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2020 auto actuals1 = presentedSurfaceFrame1.getActuals();
2021 EXPECT_EQ(actuals1.presentTime, 0);
2022
2023 // Trigger a flush by finalizing the next DisplayFrame
2024 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002025 FrameTimelineInfo ftInfo2;
2026 ftInfo2.vsyncId = surfaceFrameToken2;
2027 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002028 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002029 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2030 sLayerNameOne, sLayerNameOne,
2031 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002032 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002033 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002034 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2035 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002036 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002037 auto displayFrame2 = getDisplayFrame(1);
2038 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2039
2040 // Fences for the first frame have flushed, so the present timestamps should be updated
2041 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
2042 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2043 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2044 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00002045 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002046
2047 actuals1 = presentedSurfaceFrame1.getActuals();
2048 EXPECT_EQ(actuals1.presentTime, 30);
2049 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2050 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2051 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00002052 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002053
2054 // Fences for the second frame haven't been flushed yet, so it should be 0
2055 presentFence2->signalForTest(65);
2056 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2057 auto actuals2 = presentedSurfaceFrame2.getActuals();
2058 EXPECT_EQ(actuals2.presentTime, 0);
2059
Alec Mouri363faf02021-01-29 16:34:55 -08002060 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
2061
2062 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002063 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
2064 sLayerNameOne, sGameMode,
2065 JankType::PredictionError, -3, 5,
2066 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08002067
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002068 addEmptyDisplayFrame();
2069
2070 // Fences for the second frame have flushed, so the present timestamps should be updated
2071 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
2072 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2073 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2074 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002075 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002076
2077 actuals2 = presentedSurfaceFrame2.getActuals();
2078 EXPECT_EQ(actuals2.presentTime, 65);
2079 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2080 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2081 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002082 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002083}
2084
2085TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08002086 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002087 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002088 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
2089 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002090 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
2091 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08002092 FrameTimelineInfo ftInfo;
2093 ftInfo.vsyncId = surfaceFrameToken1;
2094 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002095 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002096 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2097 sLayerNameOne, sLayerNameOne,
2098 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002099 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002100 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002101 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2102 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2103 mFrameTimeline->setSfPresent(26, presentFence1);
2104 auto displayFrame1 = getDisplayFrame(0);
2105 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2106 presentFence1->signalForTest(50);
2107
2108 // Fences for the first frame haven't been flushed yet, so it should be 0
2109 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2110 auto actuals1 = presentedSurfaceFrame1.getActuals();
2111 EXPECT_EQ(actuals1.presentTime, 0);
2112
2113 // Trigger a flush by finalizing the next DisplayFrame
2114 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002115 FrameTimelineInfo ftInfo2;
2116 ftInfo2.vsyncId = surfaceFrameToken2;
2117 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002118 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002119 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2120 sLayerNameOne, sLayerNameOne,
2121 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002122 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002123 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002124 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2125 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002126 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002127 auto displayFrame2 = getDisplayFrame(1);
2128 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2129
2130 // Fences for the first frame have flushed, so the present timestamps should be updated
2131 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
2132 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2133 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2134 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002135 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002136
2137 actuals1 = presentedSurfaceFrame1.getActuals();
2138 EXPECT_EQ(actuals1.presentTime, 50);
2139 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2140 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2141 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002142 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002143
2144 // Fences for the second frame haven't been flushed yet, so it should be 0
2145 presentFence2->signalForTest(86);
2146 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2147 auto actuals2 = presentedSurfaceFrame2.getActuals();
2148 EXPECT_EQ(actuals2.presentTime, 0);
2149
Alec Mouri363faf02021-01-29 16:34:55 -08002150 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
2151
2152 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002153 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
2154 sLayerNameOne, sGameMode,
2155 JankType::PredictionError, -3, 5,
2156 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08002157
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002158 addEmptyDisplayFrame();
2159
2160 // Fences for the second frame have flushed, so the present timestamps should be updated
2161 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
2162 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2163 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2164 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002165 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002166
2167 actuals2 = presentedSurfaceFrame2.getActuals();
2168 EXPECT_EQ(actuals2.presentTime, 86);
2169 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2170 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2171 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002172 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002173}
2174
2175TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08002176 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08002177
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002178 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002179 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002180 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -08002181 FrameTimelineInfo ftInfo;
2182 ftInfo.vsyncId = surfaceFrameToken1;
2183 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002184 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002185 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2186 sLayerNameOne, sLayerNameOne,
2187 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002188 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002189 mFrameTimeline->setSfWakeUp(sfToken1, 42, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002190 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2191 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2192 mFrameTimeline->setSfPresent(46, presentFence1);
2193 auto displayFrame1 = getDisplayFrame(0);
2194 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2195 presentFence1->signalForTest(50);
2196
2197 // Fences for the first frame haven't been flushed yet, so it should be 0
2198 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2199 auto actuals1 = presentedSurfaceFrame1.getActuals();
2200 EXPECT_EQ(actuals1.presentTime, 0);
2201
2202 addEmptyDisplayFrame();
2203
2204 // Fences for the first frame have flushed, so the present timestamps should be updated
2205 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
2206 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2207 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2208 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002209 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002210
2211 actuals1 = presentedSurfaceFrame1.getActuals();
2212 EXPECT_EQ(actuals1.presentTime, 50);
2213 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2214 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2215 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +00002216 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002217}
2218
2219TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002220 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as only
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002221 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002222 // jank to the SurfaceFrame along with AppDeadlineMissed.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002223
Alec Mouri363faf02021-01-29 16:34:55 -08002224 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002225 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002226 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
2227 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002228 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
2229 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
Huihong Luo3bdef862022-03-03 11:57:19 -08002230 FrameTimelineInfo ftInfo;
2231 ftInfo.vsyncId = surfaceFrameToken1;
2232 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002233 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002234 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2235 sLayerNameOne, sLayerNameOne,
2236 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002237 surfaceFrame1->setAcquireFenceTime(26);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002238 mFrameTimeline->setSfWakeUp(sfToken1, 32, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002239 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2240 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2241 mFrameTimeline->setSfPresent(36, presentFence1);
2242 auto displayFrame1 = getDisplayFrame(0);
2243 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2244 presentFence1->signalForTest(40);
2245
2246 // Fences for the first frame haven't been flushed yet, so it should be 0
2247 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2248 auto actuals1 = presentedSurfaceFrame1.getActuals();
2249 EXPECT_EQ(actuals1.presentTime, 0);
2250
2251 // Trigger a flush by finalizing the next DisplayFrame
2252 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002253 FrameTimelineInfo ftInfo2;
2254 ftInfo2.vsyncId = surfaceFrameToken2;
2255 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002256 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002257 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2258 sLayerNameOne, sLayerNameOne,
2259 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002260 surfaceFrame2->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002261 mFrameTimeline->setSfWakeUp(sfToken2, 43, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002262 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2263 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2264 mFrameTimeline->setSfPresent(56, presentFence2);
2265 auto displayFrame2 = getDisplayFrame(1);
2266 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2267
2268 // Fences for the first frame have flushed, so the present timestamps should be updated
2269 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
2270 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2271 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2272 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002273 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002274
2275 actuals1 = presentedSurfaceFrame1.getActuals();
2276 EXPECT_EQ(actuals1.presentTime, 40);
2277 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2278 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2279 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002280 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002281
2282 // Fences for the second frame haven't been flushed yet, so it should be 0
2283 presentFence2->signalForTest(60);
2284 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2285 auto actuals2 = presentedSurfaceFrame2.getActuals();
2286 EXPECT_EQ(actuals2.presentTime, 0);
2287
2288 addEmptyDisplayFrame();
2289
2290 // Fences for the second frame have flushed, so the present timestamps should be updated
2291 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
2292 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2293 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2294 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002295 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002296
2297 actuals2 = presentedSurfaceFrame2.getActuals();
2298 EXPECT_EQ(actuals2.presentTime, 60);
2299 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2300 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002301 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2302 JankType::SurfaceFlingerCpuDeadlineMissed | JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002303 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002304}
2305
2306TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002307 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08002308 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002309 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2310 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2311 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2312
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002313 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2314 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Huihong Luo3bdef862022-03-03 11:57:19 -08002315 FrameTimelineInfo ftInfo;
2316 ftInfo.vsyncId = surfaceFrameToken1;
2317 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002318 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002319 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2320 sLayerNameOne, sLayerNameOne,
2321 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002322 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002323 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002324 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2325 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2326 mFrameTimeline->setSfPresent(56, presentFence1);
2327 auto displayFrame1 = getDisplayFrame(0);
2328 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2329 presentFence1->signalForTest(60);
2330
2331 // Fences for the first frame haven't been flushed yet, so it should be 0
2332 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2333 auto actuals1 = presentedSurfaceFrame1.getActuals();
2334 EXPECT_EQ(actuals1.presentTime, 0);
2335
2336 // Trigger a flush by finalizing the next DisplayFrame
2337 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002338 FrameTimelineInfo ftInfo2;
2339 ftInfo2.vsyncId = surfaceFrameToken2;
2340 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002341 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002342 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2343 sLayerNameOne, sLayerNameOne,
2344 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002345 surfaceFrame2->setAcquireFenceTime(84);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002346 mFrameTimeline->setSfWakeUp(sfToken2, 112, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002347 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2348 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2349 mFrameTimeline->setSfPresent(116, presentFence2);
2350 auto displayFrame2 = getDisplayFrame(1);
2351 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2352 presentFence2->signalForTest(120);
2353
2354 // Fences for the first frame have flushed, so the present timestamps should be updated
2355 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2356 actuals1 = presentedSurfaceFrame1.getActuals();
2357 EXPECT_EQ(actuals1.endTime, 50);
2358 EXPECT_EQ(actuals1.presentTime, 60);
2359
2360 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2361 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2362 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002363 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002364
2365 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2366 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2367 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002368 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002369
2370 // Fences for the second frame haven't been flushed yet, so it should be 0
2371 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2372 auto actuals2 = presentedSurfaceFrame2.getActuals();
2373 EXPECT_EQ(actuals2.presentTime, 0);
2374
2375 addEmptyDisplayFrame();
2376
2377 // Fences for the second frame have flushed, so the present timestamps should be updated
2378 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
2379 actuals2 = presentedSurfaceFrame2.getActuals();
2380 EXPECT_EQ(actuals2.presentTime, 120);
2381
2382 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2383 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2384 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002385 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002386
2387 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2388 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2389 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2390 JankType::AppDeadlineMissed | JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00002391 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002392}
Alec Mouriadebf5c2021-01-05 12:57:36 -08002393
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002394TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
2395 // Layer specific increment
2396 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
2397 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2398 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2399 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2400
2401 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2402 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -08002403 FrameTimelineInfo ftInfo;
2404 ftInfo.vsyncId = surfaceFrameToken1;
2405 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002406 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002407 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2408 sLayerNameOne, sLayerNameOne,
2409 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002410 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002411 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002412 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2413 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2414 mFrameTimeline->setSfPresent(56, presentFence1);
2415 auto displayFrame1 = getDisplayFrame(0);
2416 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2417 presentFence1->signalForTest(60);
2418
2419 // Fences for the first frame haven't been flushed yet, so it should be 0
2420 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2421 auto actuals1 = presentedSurfaceFrame1.getActuals();
2422 EXPECT_EQ(actuals1.presentTime, 0);
2423
2424 // Trigger a flush by finalizing the next DisplayFrame
2425 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002426 FrameTimelineInfo ftInfo2;
2427 ftInfo2.vsyncId = surfaceFrameToken2;
2428 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002429 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002430 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2431 sLayerNameOne, sLayerNameOne,
2432 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002433 surfaceFrame2->setAcquireFenceTime(80);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002434 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002435 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
2436 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2437 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2438 mFrameTimeline->setSfPresent(86, presentFence2);
2439 auto displayFrame2 = getDisplayFrame(1);
2440 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2441 presentFence2->signalForTest(90);
2442
2443 // Fences for the first frame have flushed, so the present timestamps should be updated
2444 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2445 actuals1 = presentedSurfaceFrame1.getActuals();
2446 EXPECT_EQ(actuals1.endTime, 50);
2447 EXPECT_EQ(actuals1.presentTime, 60);
2448
2449 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2450 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2451 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002452 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002453
2454 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2455 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2456 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002457 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002458
2459 // Fences for the second frame haven't been flushed yet, so it should be 0
2460 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2461 auto actuals2 = presentedSurfaceFrame2.getActuals();
2462 EXPECT_EQ(actuals2.presentTime, 0);
2463
2464 addEmptyDisplayFrame();
2465
2466 // Fences for the second frame have flushed, so the present timestamps should be updated
2467 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2468 actuals2 = presentedSurfaceFrame2.getActuals();
2469 EXPECT_EQ(actuals2.presentTime, 90);
2470
2471 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2472 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2473 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002474 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002475
2476 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2477 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2478 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00002479 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002480}
2481
Rachel Lee94917b32022-03-18 17:52:09 -07002482TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent_GpuAndCpuMiss) {
2483 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2484 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2485 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2486 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2487 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2488
2489 // Case 1: cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002490 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Rachel Lee94917b32022-03-18 17:52:09 -07002491 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
2492 auto displayFrame = getDisplayFrame(0);
2493 gpuFence1->signalForTest(36);
2494 presentFence1->signalForTest(52);
2495
2496 // Fences haven't been flushed yet, so it should be 0
2497 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
2498
2499 addEmptyDisplayFrame();
2500 displayFrame = getDisplayFrame(0);
2501
2502 // Fences have flushed, so the present timestamps should be updated
2503 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
2504 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2505 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2506 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002507 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Full);
Rachel Lee94917b32022-03-18 17:52:09 -07002508
2509 // Case 2: No GPU fence so it will not use GPU composition.
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002510 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Rachel Lee94917b32022-03-18 17:52:09 -07002511 mFrameTimeline->setSfPresent(66, presentFence2);
2512 auto displayFrame2 = getDisplayFrame(2); // 2 because of previous empty frame
2513 presentFence2->signalForTest(90);
2514
2515 // Fences for the frame haven't been flushed yet, so it should be 0
2516 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2517
2518 addEmptyDisplayFrame();
2519
2520 // Fences have flushed, so the present timestamps should be updated
2521 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2522 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2523 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2524 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002525 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Rachel Lee94917b32022-03-18 17:52:09 -07002526}
2527
Ady Abrahamfcb16862022-10-10 14:35:21 -07002528TEST_F(FrameTimelineTest, jankClassification_presentFenceError) {
2529 auto erroneousPresentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2530 auto erroneousPresentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2531 auto validPresentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2532 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2533 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2534 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({72, 80, 80});
2535
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002536 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002537 mFrameTimeline->setSfPresent(26, erroneousPresentFence1);
2538
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002539 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002540 mFrameTimeline->setSfPresent(60, erroneousPresentFence2);
2541
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002542 mFrameTimeline->setSfWakeUp(sfToken3, 72, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002543 mFrameTimeline->setSfPresent(80, validPresentFence);
2544
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002545 erroneousPresentFence2->signalForTest(2);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002546 validPresentFence->signalForTest(80);
2547
2548 addEmptyDisplayFrame();
2549
2550 {
2551 auto displayFrame = getDisplayFrame(0);
2552 EXPECT_EQ(displayFrame->getActuals().presentTime, 26);
2553 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2554 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002555 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002556 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002557 }
2558 {
2559 auto displayFrame = getDisplayFrame(1);
2560 EXPECT_EQ(displayFrame->getActuals().presentTime, 60);
2561 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2562 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002563 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002564 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002565 }
2566 {
2567 auto displayFrame = getDisplayFrame(2);
2568 EXPECT_EQ(displayFrame->getActuals().presentTime, 80);
2569 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2570 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2571 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002572 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::None);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002573 }
2574}
2575
Alec Mouriadebf5c2021-01-05 12:57:36 -08002576TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
2577 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
2578}
2579
2580TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002581 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002582
2583 auto surfaceFrame1 =
2584 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002585 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002586 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002587 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2588 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2589 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2590 presentFence1->signalForTest(oneHundredMs);
2591 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2592
2593 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2594}
2595
2596TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002597 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2598 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002599 auto surfaceFrame1 =
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 presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2604 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2605 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2606 presentFence1->signalForTest(oneHundredMs);
2607 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2608
2609 auto surfaceFrame2 =
2610 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002611 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002612 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002613 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2614 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2615 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2616 presentFence2->signalForTest(twoHundredMs);
2617 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2618
2619 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
2620}
2621
2622TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002623 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2624 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002625 auto surfaceFrame1 =
2626 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002627 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002628 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002629 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2630 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2631 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2632 presentFence1->signalForTest(oneHundredMs);
2633 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2634
2635 auto surfaceFrame2 =
2636 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002637 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002638 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002639 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2640 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2641 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2642 presentFence2->signalForTest(twoHundredMs);
2643 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2644
2645 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
2646}
2647
2648TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002649 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2650 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002651 auto surfaceFrame1 =
2652 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002653 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002654 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002655 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2656 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2657 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2658 presentFence1->signalForTest(oneHundredMs);
2659 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2660
2661 auto surfaceFrame2 =
2662 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002663 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002664 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002665 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2666 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2667 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2668 presentFence2->signalForTest(twoHundredMs);
2669 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2670
2671 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2672}
2673
2674TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002675 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2676 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2677 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2678 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2679 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002680 auto surfaceFrame1 =
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 presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2685 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2686 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2687 presentFence1->signalForTest(oneHundredMs);
2688 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2689
2690 auto surfaceFrame2 =
2691 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002692 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002693 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002694 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2695 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2696 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2697 presentFence2->signalForTest(twoHundredMs);
2698 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2699
2700 auto surfaceFrame3 =
2701 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002702 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002703 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002704 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2705 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2706 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2707 presentFence3->signalForTest(threeHundredMs);
2708 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2709
2710 auto surfaceFrame4 =
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 presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2715 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2716 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2717 presentFence4->signalForTest(fiveHundredMs);
2718 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2719
2720 auto surfaceFrame5 =
2721 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002722 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002723 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002724 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2725 // Dropped frames will be excluded from fps computation
2726 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2727 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2728 presentFence5->signalForTest(sixHundredMs);
2729 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2730
2731 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2732}
2733
ramindaniea2bb822022-06-27 19:52:10 +00002734TEST_F(FrameTimelineTest, getMinTime) {
2735 // Use SurfaceFrame::getBaseTime to test the getMinTime.
2736 FrameTimelineInfo ftInfo;
2737
2738 // Valid prediction state test.
2739 ftInfo.vsyncId = 0L;
2740 mTokenManager->generateTokenForPredictions({10});
2741 auto surfaceFrame =
2742 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2743 sLayerNameOne, sLayerNameOne,
2744 /*isBuffer*/ true, sGameMode);
2745 ASSERT_EQ(surfaceFrame->getBaseTime(), 10);
2746
2747 // Test prediction state which is not valid.
2748 ftInfo.vsyncId = FrameTimelineInfo::INVALID_VSYNC_ID;
2749 surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2750 sLayerNameOne, sLayerNameOne,
2751 /*isBuffer*/ true, sGameMode);
2752 // Start time test.
2753 surfaceFrame->setActualStartTime(200);
2754 ASSERT_EQ(surfaceFrame->getBaseTime(), 200);
2755
2756 // End time test.
2757 surfaceFrame->setAcquireFenceTime(100);
2758 ASSERT_EQ(surfaceFrame->getBaseTime(), 100);
2759
2760 // Present time test.
2761 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2762 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2763 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2764 presentFence->signalForTest(std::chrono::nanoseconds(50ns).count());
2765 mFrameTimeline->setSfPresent(50, presentFence);
2766 ASSERT_EQ(surfaceFrame->getBaseTime(), 50);
2767}
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002768
2769TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingDisplayRate) {
2770 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2771 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2772 FrameTimelineInfo ftInfo;
2773 ftInfo.vsyncId = token1;
2774 ftInfo.inputEventId = sInputEventId;
2775 auto surfaceFrame =
2776 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2777 sLayerNameOne, sLayerNameOne,
2778 /*isBuffer*/ true, sGameMode);
2779
2780 mFrameTimeline->setSfWakeUp(token1, 20, RR_30, RR_11);
2781 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2782 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2783 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2784 mFrameTimeline->setSfPresent(50, presentFence1);
2785
2786 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 11);
2787}
2788
2789TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingAppFrameRate) {
2790 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2791 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2792 FrameTimelineInfo ftInfo;
2793 ftInfo.vsyncId = token1;
2794 ftInfo.inputEventId = sInputEventId;
2795 auto surfaceFrame =
2796 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2797 sLayerNameOne, sLayerNameOne,
2798 /*isBuffer*/ true, sGameMode);
2799 surfaceFrame->setRenderRate(RR_30);
2800 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
2801 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2802 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2803 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2804 mFrameTimeline->setSfPresent(50, presentFence1);
2805
2806 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 30);
2807}
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002808} // namespace android::frametimeline