blob: e0400280fe2fa68b3f9769ceaffac46dd9d7d0bc [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
Alec Mouri9a29e672020-09-14 12:39:14 -070017#include "gmock/gmock-spec-builders.h"
18#include "mock/MockTimeStats.h"
Adithya Srinivasanf279e042020-08-17 14:56:27 -070019#undef LOG_TAG
20#define LOG_TAG "LibSurfaceFlingerUnittests"
21
22#include <FrameTimeline/FrameTimeline.h>
23#include <gtest/gtest.h>
24#include <log/log.h>
Adithya Srinivasan01189672020-10-20 14:23:05 -070025#include <perfetto/trace/trace.pb.h>
Adithya Srinivasanf279e042020-08-17 14:56:27 -070026#include <cinttypes>
27
28using namespace std::chrono_literals;
Alec Mouri363faf02021-01-29 16:34:55 -080029using testing::_;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -080030using testing::AtLeast;
Alec Mouri9a29e672020-09-14 12:39:14 -070031using testing::Contains;
Adithya Srinivasan01189672020-10-20 14:23:05 -070032using FrameTimelineEvent = perfetto::protos::FrameTimelineEvent;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000033using ProtoExpectedDisplayFrameStart =
34 perfetto::protos::FrameTimelineEvent_ExpectedDisplayFrameStart;
35using ProtoExpectedSurfaceFrameStart =
36 perfetto::protos::FrameTimelineEvent_ExpectedSurfaceFrameStart;
37using ProtoActualDisplayFrameStart = perfetto::protos::FrameTimelineEvent_ActualDisplayFrameStart;
38using ProtoActualSurfaceFrameStart = perfetto::protos::FrameTimelineEvent_ActualSurfaceFrameStart;
39using ProtoFrameEnd = perfetto::protos::FrameTimelineEvent_FrameEnd;
Adithya Srinivasan01189672020-10-20 14:23:05 -070040using ProtoPresentType = perfetto::protos::FrameTimelineEvent_PresentType;
41using ProtoJankType = perfetto::protos::FrameTimelineEvent_JankType;
Adithya Srinivasan78e58af2021-02-25 00:08:08 +000042using ProtoPredictionType = perfetto::protos::FrameTimelineEvent_PredictionType;
Alec Mouri9a29e672020-09-14 12:39:14 -070043
Adithya Srinivasanf279e042020-08-17 14:56:27 -070044namespace android::frametimeline {
45
Ady Abraham57a8ab42023-01-26 15:28:19 -080046static const std::string sLayerNameOne = "layer1";
47static const std::string sLayerNameTwo = "layer2";
48
49constexpr const uid_t sUidOne = 0;
50constexpr pid_t sPidOne = 10;
51constexpr pid_t sPidTwo = 20;
52constexpr int32_t sInputEventId = 5;
53constexpr int32_t sLayerIdOne = 1;
54constexpr int32_t sLayerIdTwo = 2;
55constexpr GameMode sGameMode = GameMode::Unsupported;
Pascal Muetschardac7bcd92023-10-03 15:05:36 +020056constexpr Fps RR_11 = Fps::fromPeriodNsecs(11);
57constexpr Fps RR_30 = Fps::fromPeriodNsecs(30);
Ady Abraham57a8ab42023-01-26 15:28:19 -080058
Adithya Srinivasanf279e042020-08-17 14:56:27 -070059class FrameTimelineTest : public testing::Test {
60public:
61 FrameTimelineTest() {
62 const ::testing::TestInfo* const test_info =
63 ::testing::UnitTest::GetInstance()->current_test_info();
64 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
65 }
66
67 ~FrameTimelineTest() {
68 const ::testing::TestInfo* const test_info =
69 ::testing::UnitTest::GetInstance()->current_test_info();
70 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
71 }
72
Adithya Srinivasan01189672020-10-20 14:23:05 -070073 static void SetUpTestSuite() {
74 // Need to initialize tracing in process for testing, and only once per test suite.
75 perfetto::TracingInitArgs args;
76 args.backends = perfetto::kInProcessBackend;
77 perfetto::Tracing::Initialize(args);
78 }
79
Adithya Srinivasanf279e042020-08-17 14:56:27 -070080 void SetUp() override {
Ady Abraham57f8e182022-03-08 15:54:33 -080081 constexpr bool kUseBootTimeClock = true;
Alec Mouri9a29e672020-09-14 12:39:14 -070082 mTimeStats = std::make_shared<mock::TimeStats>();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000083 mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats, kSurfaceFlingerPid,
Ady Abraham57f8e182022-03-08 15:54:33 -080084 kTestThresholds, !kUseBootTimeClock);
Adithya Srinivasan01189672020-10-20 14:23:05 -070085 mFrameTimeline->registerDataSource();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070086 mTokenManager = &mFrameTimeline->mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000087 mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
Adithya Srinivasan2d736322020-10-01 16:53:48 -070088 maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +000089 maxTokens = mTokenManager->kMaxTokens;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070090 }
91
Adithya Srinivasan01189672020-10-20 14:23:05 -070092 // Each tracing session can be used for a single block of Start -> Stop.
93 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
94 perfetto::TraceConfig cfg;
95 cfg.set_duration_ms(500);
96 cfg.add_buffers()->set_size_kb(1024);
97 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
98 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
99
100 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
101 tracingSession->Setup(cfg);
102 return tracingSession;
103 }
104
105 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
106 perfetto::TracingSession* tracingSession) {
107 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
108 perfetto::protos::Trace trace;
109 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
110
111 std::vector<perfetto::protos::TracePacket> packets;
112 for (const auto& packet : trace.packet()) {
113 if (!packet.has_frame_timeline_event()) {
114 continue;
115 }
116 packets.emplace_back(packet);
117 }
118 return packets;
119 }
120
Ady Abraham57a8ab42023-01-26 15:28:19 -0800121 void addEmptySurfaceFrame() {
122 auto surfaceFrame =
123 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
124 sLayerNameOne, sLayerNameOne,
125 /*isBuffer*/ false, sGameMode);
126 mFrameTimeline->addSurfaceFrame(std::move(surfaceFrame));
127 }
128
Adithya Srinivasan01189672020-10-20 14:23:05 -0700129 void addEmptyDisplayFrame() {
130 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000131 // Trigger a flushPresentFence by calling setSfPresent for the next frame
Adithya Srinivasan01189672020-10-20 14:23:05 -0700132 mFrameTimeline->setSfPresent(2500, presentFence1);
133 }
134
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000135 void flushTokens() {
136 for (size_t i = 0; i < maxTokens; i++) {
137 mTokenManager->generateTokenForPredictions({});
138 }
139 EXPECT_EQ(getPredictions().size(), maxTokens);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700140 }
141
142 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
143 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800144 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
145 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700146 }
147
148 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
149 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
150 return mFrameTimeline->mDisplayFrames[idx];
151 }
152
153 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
154 return a.startTime == b.startTime && a.endTime == b.endTime &&
155 a.presentTime == b.presentTime;
156 }
157
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000158 const std::map<int64_t, TimelineItem>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700159 return mTokenManager->mPredictions;
160 }
161
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000162 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700163 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
164 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
165 }
166
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000167 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
168
169 void flushTrace() {
170 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
171 FrameTimelineDataSource::Trace(
172 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
173 }
174
Alec Mouri9a29e672020-09-14 12:39:14 -0700175 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700176 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
177 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000178 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700179 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700180 uint32_t* maxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000181 size_t maxTokens;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000182 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasanead17162021-02-18 02:17:37 +0000183 static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan54996e22021-06-25 22:26:45 +0000184 static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(0ns).count();
Adithya Srinivasanead17162021-02-18 02:17:37 +0000185 static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800186 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
187 kDeadlineThreshold,
188 kStartThreshold};
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700189};
190
191TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
192 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000193 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000194 flushTokens();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700195 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
196 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
197
198 // token1 should have expired
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700199 EXPECT_EQ(predictions.has_value(), false);
200
201 predictions = mTokenManager->getPredictionsForToken(token2);
202 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
203}
204
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700205TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800206 auto surfaceFrame1 =
207 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000208 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000209 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -0800210 auto surfaceFrame2 =
211 mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000212 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000213 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700214 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
215 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
216}
217
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700218TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800219 auto surfaceFrame =
220 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000221 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000222 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700223 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
224}
225
226TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
227 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000228 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -0800229 FrameTimelineInfo ftInfo;
230 ftInfo.vsyncId = token1;
231 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000232 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800233 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
234 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000235 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700236
237 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
238}
239
240TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
241 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800242 FrameTimelineInfo ftInfo;
243 ftInfo.vsyncId = token1;
244 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000245 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800246 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
247 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000248 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700249
250 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
251 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
252}
253
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000254TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
255 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
256 constexpr int32_t inputEventId = 1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800257 FrameTimelineInfo ftInfo;
258 ftInfo.vsyncId = token1;
259 ftInfo.inputEventId = inputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000260 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800261 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
262 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000263 /*isBuffer*/ true, sGameMode);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000264
265 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
266}
267
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700268TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
269 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700270 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800271 FrameTimelineInfo ftInfo;
272 ftInfo.vsyncId = token1;
273 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000274 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800275 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
276 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000277 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700278
279 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200280 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000281 surfaceFrame1->setDropTime(12);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800282 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
283 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700284 mFrameTimeline->setSfPresent(25, presentFence1);
285 presentFence1->signalForTest(30);
286
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000287 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700288
289 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
290 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000291 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
292 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700293 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
294}
295
296TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800297 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800298 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700299 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
300 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700301 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800302 FrameTimelineInfo ftInfo;
303 ftInfo.vsyncId = surfaceFrameToken1;
304 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700305 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800306 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
307 sLayerNameOne, sLayerNameOne,
308 /*isBuffer*/ true, sGameMode);
Alec Mouri9a29e672020-09-14 12:39:14 -0700309 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800310 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdTwo,
311 sLayerNameTwo, sLayerNameTwo,
312 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200313 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800314 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
315 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
316 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
317 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700318 mFrameTimeline->setSfPresent(26, presentFence1);
319 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800320 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
321 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700322 presentFence1->signalForTest(42);
323
324 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800325 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700326 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
327 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
328
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000329 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700330
331 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800332 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700333 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
334 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100335 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
336 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700337}
338
339TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
340 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
341 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800342 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800343 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800344 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700345 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700346 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
347 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
348 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
349 int64_t sfToken = mTokenManager->generateTokenForPredictions(
350 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800351 FrameTimelineInfo ftInfo;
352 ftInfo.vsyncId = surfaceFrameToken;
353 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700354 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800355 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000356 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000357 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200358 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800359 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
360 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700361 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
362 presentFence->signalForTest(32 + frameTimeFactor);
363 frameTimeFactor += 30;
364 }
365 auto displayFrame0 = getDisplayFrame(0);
366
367 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800368 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700369
370 // Add one more display frame
371 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
372 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
373 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
374 int64_t sfToken = mTokenManager->generateTokenForPredictions(
375 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800376 FrameTimelineInfo ftInfo;
377 ftInfo.vsyncId = surfaceFrameToken;
378 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700379 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800380 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
381 sLayerNameOne, sLayerNameOne,
382 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200383 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800384 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
385 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700386 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
387 presentFence->signalForTest(32 + frameTimeFactor);
388 displayFrame0 = getDisplayFrame(0);
389
390 // The window should have slided by 1 now and the previous 0th display frame
391 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800392 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700393}
394
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700395TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000396 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
397 "acquireFenceAfterQueue",
398 "acquireFenceAfterQueue",
399 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700400 surfaceFrame->setActualQueueTime(123);
401 surfaceFrame->setAcquireFenceTime(456);
402 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
403}
404
405TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000406 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
407 "acquireFenceAfterQueue",
408 "acquireFenceAfterQueue",
409 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700410 surfaceFrame->setActualQueueTime(456);
411 surfaceFrame->setAcquireFenceTime(123);
412 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
413}
414
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700415TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
416 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
417 presentFence->signalForTest(2);
418
419 // Size shouldn't exceed maxDisplayFrames - 64
420 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700421 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800422 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000423 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000424 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700425 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200426 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800427 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
428 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700429 mFrameTimeline->setSfPresent(27, presentFence);
430 }
431 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
432
433 // Increase the size to 256
434 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000435 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700436
437 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700438 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800439 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000440 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000441 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700442 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200443 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800444 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
445 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700446 mFrameTimeline->setSfPresent(27, presentFence);
447 }
448 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
449
450 // Shrink the size to 128
451 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000452 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700453
454 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700455 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800456 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000457 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000458 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700459 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200460 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800461 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
462 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700463 mFrameTimeline->setSfPresent(27, presentFence);
464 }
465 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
466}
Alec Mouri9a29e672020-09-14 12:39:14 -0700467
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000468TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200469 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000470
471 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
472 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
473 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800474 FrameTimelineInfo ftInfo;
475 ftInfo.vsyncId = surfaceFrameToken1;
476 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000477
478 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800479 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
480 sLayerNameOne, sLayerNameOne,
481 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200482 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000483 surfaceFrame1->setAcquireFenceTime(20);
484 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
485 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
486
487 mFrameTimeline->setSfPresent(59, presentFence1);
488 presentFence1->signalForTest(-1);
489 addEmptyDisplayFrame();
490
491 auto displayFrame0 = getDisplayFrame(0);
Ady Abrahamfcb16862022-10-10 14:35:21 -0700492 EXPECT_EQ(displayFrame0->getActuals().presentTime, 59);
Ady Abrahamb1e10d12023-03-13 15:23:54 -0700493 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000494 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
495 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
496}
497
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800498// Tests related to TimeStats
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000499TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200500 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000501 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
502 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
503 int64_t surfaceFrameToken1 = -1;
504 int64_t sfToken1 = -1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800505 FrameTimelineInfo ftInfo;
506 ftInfo.vsyncId = surfaceFrameToken1;
507 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000508
509 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800510 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
511 sLayerNameOne, sLayerNameOne,
512 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200513 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000514 surfaceFrame1->setAcquireFenceTime(20);
515 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
516 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
517 presentFence1->signalForTest(70);
518
519 mFrameTimeline->setSfPresent(59, presentFence1);
520}
521
Alec Mouri9a29e672020-09-14 12:39:14 -0700522TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200523 Fps refreshRate = RR_11;
Alec Mouri9a29e672020-09-14 12:39:14 -0700524 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800525 incrementJankyFrames(
526 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000527 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000528 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800529 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700530 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000531 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
532 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800533 FrameTimelineInfo ftInfo;
534 ftInfo.vsyncId = surfaceFrameToken1;
535 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000536
Alec Mouri9a29e672020-09-14 12:39:14 -0700537 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800538 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
539 sLayerNameOne, sLayerNameOne,
540 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200541 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000542 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800543 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
544 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000545 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700546
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000547 mFrameTimeline->setSfPresent(62, presentFence1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700548}
549
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000550TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfGpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200551 Fps refreshRate = RR_11;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000552 EXPECT_CALL(*mTimeStats,
553 incrementJankyFrames(
554 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000555 sLayerNameOne, sGameMode,
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000556 JankType::SurfaceFlingerGpuDeadlineMissed, 4, 10,
557 0}));
558 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
559 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
560 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
561 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800562 FrameTimelineInfo ftInfo;
563 ftInfo.vsyncId = surfaceFrameToken1;
564 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000565
566 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800567 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
568 sLayerNameOne, sLayerNameOne,
569 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200570 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000571 surfaceFrame1->setAcquireFenceTime(20);
572 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
573 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
574 gpuFence1->signalForTest(64);
575 presentFence1->signalForTest(70);
576
577 mFrameTimeline->setSfPresent(59, presentFence1, gpuFence1);
578}
579
Alec Mouri9a29e672020-09-14 12:39:14 -0700580TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200581 Fps refreshRate = RR_30;
Alec Mouri9a29e672020-09-14 12:39:14 -0700582 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800583 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000584 sLayerNameOne, sGameMode,
585 JankType::DisplayHAL, -4, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800586
Alec Mouri9a29e672020-09-14 12:39:14 -0700587 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000588 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
589 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800590 FrameTimelineInfo ftInfo;
591 ftInfo.vsyncId = surfaceFrameToken1;
592 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000593
Alec Mouri9a29e672020-09-14 12:39:14 -0700594 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800595 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
596 sLayerNameOne, sLayerNameOne,
597 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200598 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800599 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000600 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800601 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000602 presentFence1->signalForTest(90);
603 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800604 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700605}
606
607TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700608 Fps refreshRate = 11_Hz;
Alec Mouri9a29e672020-09-14 12:39:14 -0700609 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000610 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000611 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000612 JankType::AppDeadlineMissed, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000613 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700614 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000615 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
616 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800617 FrameTimelineInfo ftInfo;
618 ftInfo.vsyncId = surfaceFrameToken1;
619 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000620
Alec Mouri9a29e672020-09-14 12:39:14 -0700621 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800622 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
623 sLayerNameOne, sLayerNameOne,
624 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000625 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200626 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700627
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800628 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
629 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000630 presentFence1->signalForTest(90);
631 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100632
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800633 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700634}
635
Adithya Srinivasanead17162021-02-18 02:17:37 +0000636TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000637 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000638 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000639 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000640 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000641 JankType::SurfaceFlingerScheduling,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000642 -4, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000643 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000644 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
645 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800646 FrameTimelineInfo ftInfo;
647 ftInfo.vsyncId = surfaceFrameToken1;
648 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000649
Adithya Srinivasanead17162021-02-18 02:17:37 +0000650 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800651 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
652 sLayerNameOne, sLayerNameOne,
653 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000654 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200655 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000656
657 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
658 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000659 presentFence1->signalForTest(60);
660 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000661
662 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
663}
664
665TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000666 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000667 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000668 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000669 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000670 JankType::PredictionError, -4, 5,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000671 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000672 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000673 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
674 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800675 FrameTimelineInfo ftInfo;
676 ftInfo.vsyncId = surfaceFrameToken1;
677 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000678
Adithya Srinivasanead17162021-02-18 02:17:37 +0000679 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800680 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
681 sLayerNameOne, sLayerNameOne,
682 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000683 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200684 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000685
686 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
687 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000688 presentFence1->signalForTest(65);
689 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000690
691 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
692}
693
694TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000695 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000696 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000697 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000698 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000699 JankType::BufferStuffing, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000700 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000701 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000702 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
703 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800704 FrameTimelineInfo ftInfo;
705 ftInfo.vsyncId = surfaceFrameToken1;
706 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000707
Adithya Srinivasanead17162021-02-18 02:17:37 +0000708 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800709 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
710 sLayerNameOne, sLayerNameOne,
711 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000712 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200713 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000714
715 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000716 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000717 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000718 presentFence1->signalForTest(90);
719 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000720
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000721 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000722}
723
Alec Mouri363faf02021-01-29 16:34:55 -0800724TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200725 Fps refreshRate = RR_11;
726 Fps renderRate = RR_30;
Alec Mouri363faf02021-01-29 16:34:55 -0800727 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000728 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne,
729 sLayerNameOne, sGameMode,
730 JankType::AppDeadlineMissed, -4, 0,
731 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800732 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000733 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
734 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800735 FrameTimelineInfo ftInfo;
736 ftInfo.vsyncId = surfaceFrameToken1;
737 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000738
Alec Mouri363faf02021-01-29 16:34:55 -0800739 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800740 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
741 sLayerNameOne, sLayerNameOne,
742 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000743 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200744 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800745
746 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
747 surfaceFrame1->setRenderRate(renderRate);
748 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000749 presentFence1->signalForTest(90);
750 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800751
752 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
753}
754
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000755TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200756 Fps refreshRate = RR_11;
757 Fps renderRate = RR_30;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000758
759 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000760 incrementJankyFrames(
761 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000762 sGameMode,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000763 JankType::Unknown | JankType::AppDeadlineMissed,
Adithya Srinivasande272452021-04-10 00:21:00 +0000764 0, 0, 25}));
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000765 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
766 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
767 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800768 FrameTimelineInfo ftInfo;
769 ftInfo.vsyncId = surfaceFrameToken1;
770 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000771
772 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800773 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
774 sLayerNameOne, sLayerNameOne,
775 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000776 surfaceFrame1->setAcquireFenceTime(45);
777 // Trigger a prediction expiry
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000778 flushTokens();
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200779 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000780
781 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
782 surfaceFrame1->setRenderRate(renderRate);
783 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
784 presentFence1->signalForTest(90);
785 mFrameTimeline->setSfPresent(86, presentFence1);
786
787 auto displayFrame = getDisplayFrame(0);
788 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
789 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
790 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
791 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
792
793 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000794 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000795}
796
Adithya Srinivasan01189672020-10-20 14:23:05 -0700797/*
798 * Tracing Tests
799 *
800 * Trace packets are flushed all the way only when the next packet is traced.
801 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
802 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
803 * will have additional empty frames created for this reason.
804 */
805TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
806 auto tracingSession = getTracingSessionForTest();
807 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700808 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800809 FrameTimelineInfo ftInfo;
810 ftInfo.vsyncId = token1;
811 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000812 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800813 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
814 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000815 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700816
817 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200818 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800819 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
820 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700821 mFrameTimeline->setSfPresent(25, presentFence1);
822 presentFence1->signalForTest(30);
823
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000824 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700825
826 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000827 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700828}
829
830TEST_F(FrameTimelineTest, tracing_sanityTest) {
831 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800832 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800833 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700834 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700835
836 tracingSession->StartBlocking();
837 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
838 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800839 FrameTimelineInfo ftInfo;
840 ftInfo.vsyncId = token1;
841 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000842 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800843 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
844 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000845 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700846
847 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200848 mFrameTimeline->setSfWakeUp(token2, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800849 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
850 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700851 mFrameTimeline->setSfPresent(25, presentFence1);
852 presentFence1->signalForTest(30);
853
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000854 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000855 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700856 tracingSession->StopBlocking();
857
858 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000859 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000860 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700861}
862
863TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
864 auto tracingSession = getTracingSessionForTest();
865 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700866
867 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700868
869 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200870 mFrameTimeline->setSfWakeUp(-1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700871 mFrameTimeline->setSfPresent(25, presentFence1);
872 presentFence1->signalForTest(30);
873
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000874 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000875 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700876 tracingSession->StopBlocking();
877
878 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000879 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700880}
881
882TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
883 auto tracingSession = getTracingSessionForTest();
884 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700885
886 tracingSession->StartBlocking();
887 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -0800888 auto surfaceFrame1 =
889 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000890 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 Srinivasan05bd2d12021-01-11 18:49:58 +0000901 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700902 tracingSession->StopBlocking();
903
904 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000905 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
906 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000907 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700908}
909
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000910ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
911 pid_t pid) {
912 ProtoExpectedDisplayFrameStart proto;
913 proto.set_cookie(cookie);
914 proto.set_token(token);
915 proto.set_pid(pid);
916 return proto;
917}
918
919ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
920 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000921 bool gpuComposition, ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000922 ProtoActualDisplayFrameStart proto;
923 proto.set_cookie(cookie);
924 proto.set_token(token);
925 proto.set_pid(pid);
926 proto.set_present_type(presentType);
927 proto.set_on_time_finish(onTimeFinish);
928 proto.set_gpu_composition(gpuComposition);
929 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000930 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000931 return proto;
932}
933
934ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
935 int64_t displayFrameToken,
936 pid_t pid,
937 std::string layerName) {
938 ProtoExpectedSurfaceFrameStart proto;
939 proto.set_cookie(cookie);
940 proto.set_token(token);
941 proto.set_display_frame_token(displayFrameToken);
942 proto.set_pid(pid);
943 proto.set_layer_name(layerName);
944 return proto;
945}
946
947ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
948 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
949 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +0000950 ProtoJankType jankType, ProtoPredictionType predictionType, bool isBuffer) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000951 ProtoActualSurfaceFrameStart proto;
952 proto.set_cookie(cookie);
953 proto.set_token(token);
954 proto.set_display_frame_token(displayFrameToken);
955 proto.set_pid(pid);
956 proto.set_layer_name(layerName);
957 proto.set_present_type(presentType);
958 proto.set_on_time_finish(onTimeFinish);
959 proto.set_gpu_composition(gpuComposition);
960 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000961 proto.set_prediction_type(predictionType);
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +0000962 proto.set_is_buffer(isBuffer);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000963 return proto;
964}
965
966ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
967 ProtoFrameEnd proto;
968 proto.set_cookie(cookie);
969 return proto;
970}
971
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000972void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
973 const ProtoExpectedDisplayFrameStart& source) {
974 ASSERT_TRUE(received.has_cookie());
975 EXPECT_EQ(received.cookie(), source.cookie());
976
Adithya Srinivasan01189672020-10-20 14:23:05 -0700977 ASSERT_TRUE(received.has_token());
978 EXPECT_EQ(received.token(), source.token());
979
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000980 ASSERT_TRUE(received.has_pid());
981 EXPECT_EQ(received.pid(), source.pid());
982}
983
984void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
985 const ProtoActualDisplayFrameStart& source) {
986 ASSERT_TRUE(received.has_cookie());
987 EXPECT_EQ(received.cookie(), source.cookie());
988
989 ASSERT_TRUE(received.has_token());
990 EXPECT_EQ(received.token(), source.token());
991
992 ASSERT_TRUE(received.has_pid());
993 EXPECT_EQ(received.pid(), source.pid());
994
Adithya Srinivasan01189672020-10-20 14:23:05 -0700995 ASSERT_TRUE(received.has_present_type());
996 EXPECT_EQ(received.present_type(), source.present_type());
997 ASSERT_TRUE(received.has_on_time_finish());
998 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
999 ASSERT_TRUE(received.has_gpu_composition());
1000 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1001 ASSERT_TRUE(received.has_jank_type());
1002 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001003 ASSERT_TRUE(received.has_prediction_type());
1004 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001005}
1006
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001007void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
1008 const ProtoExpectedSurfaceFrameStart& source) {
1009 ASSERT_TRUE(received.has_cookie());
1010 EXPECT_EQ(received.cookie(), source.cookie());
1011
Adithya Srinivasan01189672020-10-20 14:23:05 -07001012 ASSERT_TRUE(received.has_token());
1013 EXPECT_EQ(received.token(), source.token());
1014
1015 ASSERT_TRUE(received.has_display_frame_token());
1016 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1017
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001018 ASSERT_TRUE(received.has_pid());
1019 EXPECT_EQ(received.pid(), source.pid());
1020
1021 ASSERT_TRUE(received.has_layer_name());
1022 EXPECT_EQ(received.layer_name(), source.layer_name());
1023}
1024
1025void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
1026 const ProtoActualSurfaceFrameStart& source) {
1027 ASSERT_TRUE(received.has_cookie());
1028 EXPECT_EQ(received.cookie(), source.cookie());
1029
1030 ASSERT_TRUE(received.has_token());
1031 EXPECT_EQ(received.token(), source.token());
1032
1033 ASSERT_TRUE(received.has_display_frame_token());
1034 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1035
1036 ASSERT_TRUE(received.has_pid());
1037 EXPECT_EQ(received.pid(), source.pid());
1038
1039 ASSERT_TRUE(received.has_layer_name());
1040 EXPECT_EQ(received.layer_name(), source.layer_name());
1041
Adithya Srinivasan01189672020-10-20 14:23:05 -07001042 ASSERT_TRUE(received.has_present_type());
1043 EXPECT_EQ(received.present_type(), source.present_type());
1044 ASSERT_TRUE(received.has_on_time_finish());
1045 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1046 ASSERT_TRUE(received.has_gpu_composition());
1047 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1048 ASSERT_TRUE(received.has_jank_type());
1049 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001050 ASSERT_TRUE(received.has_prediction_type());
1051 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001052 ASSERT_TRUE(received.has_is_buffer());
1053 EXPECT_EQ(received.is_buffer(), source.is_buffer());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001054}
Adithya Srinivasan01189672020-10-20 14:23:05 -07001055
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001056void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
1057 ASSERT_TRUE(received.has_cookie());
1058 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001059}
1060
Sally Qiaa107742023-09-29 14:53:14 -07001061TEST_F(FrameTimelineTest, traceDisplayFrameSkipped) {
1062 // setup 2 display frames
1063 // DF 1: [22,40] -> [5, 40]
1064 // DF : [36, 70] (Skipped one, added by the trace)
1065 // DF 2: [82, 100] -> SF [25, 70]
1066 auto tracingSession = getTracingSessionForTest();
1067 tracingSession->StartBlocking();
1068 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1069 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 100});
1070 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1071 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1072 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1073
1074 int64_t traceCookie = snoopCurrentTraceCookie();
1075
1076 // set up 1st display frame
1077 FrameTimelineInfo ftInfo1;
1078 ftInfo1.vsyncId = surfaceFrameToken1;
1079 ftInfo1.inputEventId = sInputEventId;
1080 auto surfaceFrame1 =
1081 mFrameTimeline->createSurfaceFrameForToken(ftInfo1, sPidOne, sUidOne, sLayerIdOne,
1082 sLayerNameOne, sLayerNameOne,
1083 /*isBuffer*/ true, sGameMode);
1084 surfaceFrame1->setAcquireFenceTime(16);
1085 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_30);
1086 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1087 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1088 mFrameTimeline->setSfPresent(30, presentFence1);
1089 presentFence1->signalForTest(40);
1090
1091 // Trigger a flush by finalizing the next DisplayFrame
1092 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1093 FrameTimelineInfo ftInfo2;
1094 ftInfo2.vsyncId = surfaceFrameToken2;
1095 ftInfo2.inputEventId = sInputEventId;
1096 auto surfaceFrame2 =
1097 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1098 sLayerNameOne, sLayerNameOne,
1099 /*isBuffer*/ true, sGameMode);
1100
1101 // set up 2nd display frame
1102 surfaceFrame2->setAcquireFenceTime(36);
1103 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_11, RR_30);
1104 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1105 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1106 mFrameTimeline->setSfPresent(90, presentFence2);
1107 presentFence2->signalForTest(100);
1108
1109 // the token of skipped Display Frame
1110 auto protoSkippedActualDisplayFrameStart =
1111 createProtoActualDisplayFrameStart(traceCookie + 9, 0, kSurfaceFlingerPid,
1112 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1113 FrameTimelineEvent::JANK_DROPPED,
1114 FrameTimelineEvent::PREDICTION_VALID);
1115 auto protoSkippedActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 9);
1116
1117 // Trigger a flush by finalizing the next DisplayFrame
1118 addEmptyDisplayFrame();
1119 flushTrace();
1120 tracingSession->StopBlocking();
1121
1122 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1123 // 8 Valid Display Frames + 8 Valid Surface Frames + 2 Skipped Display Frames
1124 EXPECT_EQ(packets.size(), 18u);
1125
1126 // Packet - 16: Actual skipped Display Frame Start
1127 // the timestamp should be equal to the 2nd expected surface frame's end time
1128 const auto& packet16 = packets[16];
1129 ASSERT_TRUE(packet16.has_timestamp());
1130 EXPECT_EQ(packet16.timestamp(), 36u);
1131 ASSERT_TRUE(packet16.has_frame_timeline_event());
1132
1133 const auto& event16 = packet16.frame_timeline_event();
1134 const auto& actualSkippedDisplayFrameStart = event16.actual_display_frame_start();
1135 validateTraceEvent(actualSkippedDisplayFrameStart, protoSkippedActualDisplayFrameStart);
1136
1137 // Packet - 17: Actual skipped Display Frame End
1138 // the timestamp should be equal to the 2nd expected surface frame's present time
1139 const auto& packet17 = packets[17];
1140 ASSERT_TRUE(packet17.has_timestamp());
1141 EXPECT_EQ(packet17.timestamp(), 70u);
1142 ASSERT_TRUE(packet17.has_frame_timeline_event());
1143
1144 const auto& event17 = packet17.frame_timeline_event();
1145 const auto& actualSkippedDisplayFrameEnd = event17.frame_end();
1146 validateTraceEvent(actualSkippedDisplayFrameEnd, protoSkippedActualDisplayFrameEnd);
1147}
1148
Adithya Srinivasan01189672020-10-20 14:23:05 -07001149TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
1150 auto tracingSession = getTracingSessionForTest();
1151 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001152
1153 tracingSession->StartBlocking();
Ady Abraham57a8ab42023-01-26 15:28:19 -08001154
1155 // Add an empty surface frame so that display frame would get traced.
1156 addEmptySurfaceFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001157 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001158
1159 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001160 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001161 mFrameTimeline->setSfPresent(26, presentFence1);
1162 presentFence1->signalForTest(31);
1163
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001164 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001165 auto protoExpectedDisplayFrameStart =
1166 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1167 kSurfaceFlingerPid);
1168 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1169 auto protoActualDisplayFrameStart =
1170 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
1171 kSurfaceFlingerPid,
1172 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001173 FrameTimelineEvent::JANK_NONE,
1174 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001175 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001176
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001177 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001178 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001179 tracingSession->StopBlocking();
1180
1181 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001182 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001183
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001184 // Packet - 0 : ExpectedDisplayFrameStart
1185 const auto& packet0 = packets[0];
1186 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001187 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001188 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001189
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001190 const auto& event0 = packet0.frame_timeline_event();
1191 ASSERT_TRUE(event0.has_expected_display_frame_start());
1192 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
1193 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
1194
1195 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
1196 const auto& packet1 = packets[1];
1197 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001198 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001199 ASSERT_TRUE(packet1.has_frame_timeline_event());
1200
1201 const auto& event1 = packet1.frame_timeline_event();
1202 ASSERT_TRUE(event1.has_frame_end());
1203 const auto& expectedDisplayFrameEnd = event1.frame_end();
1204 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
1205
1206 // Packet - 2 : ActualDisplayFrameStart
1207 const auto& packet2 = packets[2];
1208 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001209 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001210 ASSERT_TRUE(packet2.has_frame_timeline_event());
1211
1212 const auto& event2 = packet2.frame_timeline_event();
1213 ASSERT_TRUE(event2.has_actual_display_frame_start());
1214 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1215 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1216
1217 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1218 const auto& packet3 = packets[3];
1219 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001220 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001221 ASSERT_TRUE(packet3.has_frame_timeline_event());
1222
1223 const auto& event3 = packet3.frame_timeline_event();
1224 ASSERT_TRUE(event3.has_frame_end());
1225 const auto& actualDisplayFrameEnd = event3.frame_end();
1226 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001227}
1228
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001229TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1230 auto tracingSession = getTracingSessionForTest();
1231 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1232
1233 tracingSession->StartBlocking();
1234 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1235 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001236 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001237
Ady Abraham57a8ab42023-01-26 15:28:19 -08001238 // Add an empty surface frame so that display frame would get traced.
1239 addEmptySurfaceFrame();
1240
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001241 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001242 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001243 mFrameTimeline->setSfPresent(26, presentFence1);
1244 presentFence1->signalForTest(31);
1245
1246 int64_t traceCookie = snoopCurrentTraceCookie();
1247
1248 auto protoActualDisplayFrameStart =
1249 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1250 kSurfaceFlingerPid,
1251 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001252 false, FrameTimelineEvent::JANK_UNKNOWN,
1253 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001254 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1255
1256 addEmptyDisplayFrame();
1257 flushTrace();
1258 tracingSession->StopBlocking();
1259
1260 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1261 // Only actual timeline packets should be in the trace
1262 EXPECT_EQ(packets.size(), 2u);
1263
1264 // Packet - 0 : ActualDisplayFrameStart
1265 const auto& packet0 = packets[0];
1266 ASSERT_TRUE(packet0.has_timestamp());
1267 EXPECT_EQ(packet0.timestamp(), 20u);
1268 ASSERT_TRUE(packet0.has_frame_timeline_event());
1269
1270 const auto& event0 = packet0.frame_timeline_event();
1271 ASSERT_TRUE(event0.has_actual_display_frame_start());
1272 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1273 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1274
1275 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1276 const auto& packet1 = packets[1];
1277 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001278 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001279 ASSERT_TRUE(packet1.has_frame_timeline_event());
1280
1281 const auto& event1 = packet1.frame_timeline_event();
1282 ASSERT_TRUE(event1.has_frame_end());
1283 const auto& actualDisplayFrameEnd = event1.frame_end();
1284 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1285}
1286
Adithya Srinivasan01189672020-10-20 14:23:05 -07001287TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1288 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001289 // Layer specific increment
Edgar Arriaga631e4252023-03-02 02:11:24 +00001290 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001291 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1292 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1293
1294 tracingSession->StartBlocking();
1295 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1296 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001297
Huihong Luo3bdef862022-03-03 11:57:19 -08001298 FrameTimelineInfo ftInfo;
1299 ftInfo.vsyncId = surfaceFrameToken;
1300 ftInfo.inputEventId = sInputEventId;
1301
Adithya Srinivasan01189672020-10-20 14:23:05 -07001302 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001303 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1304 sLayerNameOne, sLayerNameOne,
1305 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001306 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001307 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1308 sLayerNameOne, sLayerNameOne,
1309 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001310 surfaceFrame1->setActualQueueTime(10);
1311 surfaceFrame1->setDropTime(15);
1312
1313 surfaceFrame2->setActualQueueTime(15);
1314 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001315
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001316 // First 2 cookies will be used by the DisplayFrame
1317 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1318
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001319 auto protoDroppedSurfaceFrameExpectedStart =
1320 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1321 displayFrameToken1, sPidOne, sLayerNameOne);
1322 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1323 auto protoDroppedSurfaceFrameActualStart =
1324 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1325 displayFrameToken1, sPidOne, sLayerNameOne,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001326 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1327 FrameTimelineEvent::JANK_DROPPED,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001328 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001329 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001330
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001331 auto protoPresentedSurfaceFrameExpectedStart =
1332 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1333 displayFrameToken1, sPidOne, sLayerNameOne);
1334 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1335 auto protoPresentedSurfaceFrameActualStart =
1336 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1337 displayFrameToken1, sPidOne, sLayerNameOne,
1338 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001339 FrameTimelineEvent::JANK_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001340 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001341 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001342
1343 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001344 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001345 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1346 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001347 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001348 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001349 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001350 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001351
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001352 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001353 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001354 tracingSession->StopBlocking();
1355
1356 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001357 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1358 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001359
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001360 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001361 const auto& packet4 = packets[4];
1362 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001363 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001364 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001365
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001366 const auto& event4 = packet4.frame_timeline_event();
1367 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001368 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1369 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001370
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001371 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001372 const auto& packet5 = packets[5];
1373 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001374 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001375 ASSERT_TRUE(packet5.has_frame_timeline_event());
1376
1377 const auto& event5 = packet5.frame_timeline_event();
1378 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001379 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1380 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001381
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001382 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001383 const auto& packet6 = packets[6];
1384 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001385 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001386 ASSERT_TRUE(packet6.has_frame_timeline_event());
1387
1388 const auto& event6 = packet6.frame_timeline_event();
1389 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001390 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1391 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001392
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001393 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001394 const auto& packet7 = packets[7];
1395 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001396 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001397 ASSERT_TRUE(packet7.has_frame_timeline_event());
1398
1399 const auto& event7 = packet7.frame_timeline_event();
1400 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001401 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1402 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1403
1404 // Packet - 8 : ExpectedSurfaceFrameStart2
1405 const auto& packet8 = packets[8];
1406 ASSERT_TRUE(packet8.has_timestamp());
1407 EXPECT_EQ(packet8.timestamp(), 10u);
1408 ASSERT_TRUE(packet8.has_frame_timeline_event());
1409
1410 const auto& event8 = packet8.frame_timeline_event();
1411 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1412 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1413 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1414
1415 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1416 const auto& packet9 = packets[9];
1417 ASSERT_TRUE(packet9.has_timestamp());
1418 EXPECT_EQ(packet9.timestamp(), 25u);
1419 ASSERT_TRUE(packet9.has_frame_timeline_event());
1420
1421 const auto& event9 = packet9.frame_timeline_event();
1422 ASSERT_TRUE(event9.has_frame_end());
1423 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1424 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1425
1426 // Packet - 10 : ActualSurfaceFrameStart2
1427 const auto& packet10 = packets[10];
1428 ASSERT_TRUE(packet10.has_timestamp());
1429 EXPECT_EQ(packet10.timestamp(), 10u);
1430 ASSERT_TRUE(packet10.has_frame_timeline_event());
1431
1432 const auto& event10 = packet10.frame_timeline_event();
1433 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1434 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1435 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1436
1437 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1438 const auto& packet11 = packets[11];
1439 ASSERT_TRUE(packet11.has_timestamp());
1440 EXPECT_EQ(packet11.timestamp(), 20u);
1441 ASSERT_TRUE(packet11.has_frame_timeline_event());
1442
1443 const auto& event11 = packet11.frame_timeline_event();
1444 ASSERT_TRUE(event11.has_frame_end());
1445 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1446 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1447}
1448
Ady Abrahame43ff722022-02-15 14:44:25 -08001449TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredIsAppMissedDeadline) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001450 auto tracingSession = getTracingSessionForTest();
1451 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1452
1453 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001454 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1455 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1456 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001457 int64_t surfaceFrameToken =
1458 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1459
1460 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001461 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001462 FrameTimelineInfo ftInfo;
1463 ftInfo.vsyncId = surfaceFrameToken;
1464 ftInfo.inputEventId = 0;
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001465 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001466 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1467 sLayerNameOne, sLayerNameOne,
1468 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001469 surfaceFrame1->setActualQueueTime(appEndTime);
1470 surfaceFrame1->setAcquireFenceTime(appEndTime);
1471
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001472 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1473 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1474 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001475 int64_t displayFrameToken =
1476 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1477
1478 // First 2 cookies will be used by the DisplayFrame
1479 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1480
1481 auto protoActualSurfaceFrameStart =
1482 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1483 displayFrameToken, sPidOne, sLayerNameOne,
1484 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Ady Abrahame43ff722022-02-15 14:44:25 -08001485 false, FrameTimelineEvent::JANK_APP_DEADLINE_MISSED,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001486 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001487 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1488
1489 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001490 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001491 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1492 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1493 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1494 presentFence1->signalForTest(sfPresentTime);
1495
1496 addEmptyDisplayFrame();
1497 flushTrace();
1498 tracingSession->StopBlocking();
1499
1500 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1501 // Display Frame 4 packets + SurfaceFrame 2 packets
1502 ASSERT_EQ(packets.size(), 6u);
1503
1504 // Packet - 4 : ActualSurfaceFrameStart
1505 const auto& packet4 = packets[4];
1506 ASSERT_TRUE(packet4.has_timestamp());
1507 EXPECT_EQ(packet4.timestamp(),
1508 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1509 ASSERT_TRUE(packet4.has_frame_timeline_event());
1510
1511 const auto& event4 = packet4.frame_timeline_event();
1512 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1513 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1514 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1515
1516 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1517 const auto& packet5 = packets[5];
1518 ASSERT_TRUE(packet5.has_timestamp());
1519 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1520 ASSERT_TRUE(packet5.has_frame_timeline_event());
1521
1522 const auto& event5 = packet5.frame_timeline_event();
1523 ASSERT_TRUE(event5.has_frame_end());
1524 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001525 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001526}
1527
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001528TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDroppedFramesTracedProperly) {
1529 auto tracingSession = getTracingSessionForTest();
1530 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1531
1532 tracingSession->StartBlocking();
1533 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1534 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1535 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
1536 int64_t surfaceFrameToken =
1537 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1538
1539 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001540 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001541 FrameTimelineInfo ftInfo;
1542 ftInfo.vsyncId = surfaceFrameToken;
1543 ftInfo.inputEventId = 0;
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001544 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001545 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1546 sLayerNameOne, sLayerNameOne,
1547 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001548
1549 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(22ms).count();
1550 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1551 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
1552 int64_t displayFrameToken =
1553 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1554
1555 // First 2 cookies will be used by the DisplayFrame
1556 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1557
1558 auto protoActualSurfaceFrameStart =
1559 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1560 displayFrameToken, sPidOne, sLayerNameOne,
1561 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001562 FrameTimelineEvent::JANK_DROPPED,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001563 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001564 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1565
1566 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001567 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001568 surfaceFrame1->setDropTime(sfStartTime);
1569 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1570 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1571 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1572 presentFence1->signalForTest(sfPresentTime);
1573
1574 addEmptyDisplayFrame();
1575 flushTrace();
1576 tracingSession->StopBlocking();
1577
1578 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1579 // Display Frame 4 packets + SurfaceFrame 2 packets
1580 ASSERT_EQ(packets.size(), 6u);
1581
1582 // Packet - 4 : ActualSurfaceFrameStart
1583 const auto& packet4 = packets[4];
1584 ASSERT_TRUE(packet4.has_timestamp());
1585 EXPECT_EQ(packet4.timestamp(),
1586 static_cast<uint64_t>(sfStartTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1587 ASSERT_TRUE(packet4.has_frame_timeline_event());
1588
1589 const auto& event4 = packet4.frame_timeline_event();
1590 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1591 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1592 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1593
1594 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1595 const auto& packet5 = packets[5];
1596 ASSERT_TRUE(packet5.has_timestamp());
1597 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(sfStartTime));
1598 ASSERT_TRUE(packet5.has_frame_timeline_event());
1599
1600 const auto& event5 = packet5.frame_timeline_event();
1601 ASSERT_TRUE(event5.has_frame_end());
1602 const auto& actualSurfaceFrameEnd = event5.frame_end();
1603 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
1604}
1605
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001606// Tests for Jank classification
1607TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001608 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001609 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001610 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1611 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001612 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -08001613 FrameTimelineInfo ftInfo;
1614 ftInfo.vsyncId = surfaceFrameToken;
1615 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001616 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -08001617 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1618 sLayerNameOne, sLayerNameOne,
1619 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001620 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001621 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1622 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1623 mFrameTimeline->setSfPresent(26, presentFence1);
1624 auto displayFrame = getDisplayFrame(0);
1625 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1626 presentFence1->signalForTest(29);
1627
1628 // Fences haven't been flushed yet, so it should be 0
1629 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1630 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1631
1632 addEmptyDisplayFrame();
1633 displayFrame = getDisplayFrame(0);
1634
1635 // Fences have flushed, so the present timestamps should be updated
1636 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1637 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1638 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1639 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1640 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
1641}
1642
1643TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001644 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001645 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001646 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1647 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001648 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001649 mFrameTimeline->setSfPresent(26, presentFence1);
1650 auto displayFrame = getDisplayFrame(0);
1651 presentFence1->signalForTest(30);
1652
1653 // Fences for the first frame haven't been flushed yet, so it should be 0
1654 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1655
1656 // Trigger a flush by finalizing the next DisplayFrame
1657 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001658 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001659 mFrameTimeline->setSfPresent(56, presentFence2);
1660 displayFrame = getDisplayFrame(0);
1661
1662 // Fences for the first frame have flushed, so the present timestamps should be updated
1663 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1664 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1665 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1666 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1667
1668 // Fences for the second frame haven't been flushed yet, so it should be 0
1669 auto displayFrame2 = getDisplayFrame(1);
1670 presentFence2->signalForTest(65);
1671 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001672 addEmptyDisplayFrame();
1673 displayFrame2 = getDisplayFrame(1);
1674
1675 // Fences for the second frame have flushed, so the present timestamps should be updated
1676 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1677 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1678 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1679 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1680}
1681
1682TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001683 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001684 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001685 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1686 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001687 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001688 mFrameTimeline->setSfPresent(26, presentFence1);
1689 auto displayFrame = getDisplayFrame(0);
1690 presentFence1->signalForTest(50);
1691
1692 // Fences for the first frame haven't been flushed yet, so it should be 0
1693 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1694
1695 // Trigger a flush by finalizing the next DisplayFrame
1696 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001697 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001698 mFrameTimeline->setSfPresent(56, presentFence2);
1699 displayFrame = getDisplayFrame(0);
1700
1701 // Fences for the first frame have flushed, so the present timestamps should be updated
1702 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1703 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1704 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1705 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1706
1707 // Fences for the second frame haven't been flushed yet, so it should be 0
1708 auto displayFrame2 = getDisplayFrame(1);
1709 presentFence2->signalForTest(75);
1710 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1711
1712 addEmptyDisplayFrame();
1713 displayFrame2 = getDisplayFrame(1);
1714
1715 // Fences for the second frame have flushed, so the present timestamps should be updated
1716 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1717 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1718 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1719 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1720}
1721
1722TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001723 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1724 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001725 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001726
1727 mFrameTimeline->setSfPresent(22, presentFence1);
1728 auto displayFrame = getDisplayFrame(0);
1729 presentFence1->signalForTest(28);
1730
1731 // Fences haven't been flushed yet, so it should be 0
1732 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1733
1734 addEmptyDisplayFrame();
1735 displayFrame = getDisplayFrame(0);
1736
1737 // Fences have flushed, so the present timestamps should be updated
1738 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1739 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1740 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1741 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1742}
1743
1744TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001745 /*
1746 * Case 1 - cpu time > vsync period but combined time > deadline > deadline -> cpudeadlinemissed
1747 * Case 2 - cpu time < vsync period but combined time > deadline -> gpudeadlinemissed
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001748 * Case 3 - previous frame ran longer -> sf_stuffing
1749 * Case 4 - Long cpu under SF stuffing -> cpudeadlinemissed
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001750 */
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001751 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001752 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001753 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1754 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001755 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1756 auto gpuFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001757 auto gpuFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1758 auto gpuFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001759 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001760 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001761 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1762 int64_t sfToken4 = mTokenManager->generateTokenForPredictions({112, 120, 120});
1763
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001764 // case 1 - cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001765 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001766 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
1767 auto displayFrame0 = getDisplayFrame(0);
1768 gpuFence1->signalForTest(36);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001769 presentFence1->signalForTest(52);
1770
1771 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001772 EXPECT_EQ(displayFrame0->getActuals().presentTime, 0);
1773
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001774 // case 2 - cpu time = 56 - 52 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001775 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001776 mFrameTimeline->setSfPresent(56, presentFence2, gpuFence2);
1777 auto displayFrame1 = getDisplayFrame(1);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001778 gpuFence2->signalForTest(76);
1779 presentFence2->signalForTest(90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001780
1781 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1782 // Fences have flushed for first displayFrame, so the present timestamps should be updated
1783 EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
1784 EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1785 EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Rachel Lee94917b32022-03-18 17:52:09 -07001786 EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001787
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001788 // case 3 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001789 mFrameTimeline->setSfWakeUp(sfToken3, 106, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001790 mFrameTimeline->setSfPresent(112, presentFence3, gpuFence3);
1791 auto displayFrame2 = getDisplayFrame(2);
1792 gpuFence3->signalForTest(116);
1793 presentFence3->signalForTest(120);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001794
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001795 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001796 // Fences have flushed for second displayFrame, so the present timestamps should be updated
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001797 EXPECT_EQ(displayFrame1->getActuals().presentTime, 90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001798 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1799 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1800 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001801
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001802 // case 4 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001803 mFrameTimeline->setSfWakeUp(sfToken4, 120, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001804 mFrameTimeline->setSfPresent(140, presentFence4, gpuFence4);
1805 auto displayFrame3 = getDisplayFrame(3);
1806 gpuFence4->signalForTest(156);
1807 presentFence4->signalForTest(180);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001808
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001809 EXPECT_EQ(displayFrame3->getActuals().presentTime, 0);
1810 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1811 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1812 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1813 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1814 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerStuffing);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001815
1816 addEmptyDisplayFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001817
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001818 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1819 EXPECT_EQ(displayFrame3->getActuals().presentTime, 180);
1820 EXPECT_EQ(displayFrame3->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1821 EXPECT_EQ(displayFrame3->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1822 EXPECT_EQ(displayFrame3->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001823}
1824
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001825TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001826 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001827 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001828 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1829 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001830 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1831 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08001832 FrameTimelineInfo ftInfo;
1833 ftInfo.vsyncId = surfaceFrameToken1;
1834 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001835 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001836 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1837 sLayerNameOne, sLayerNameOne,
1838 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001839 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001840 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001841 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1842 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001843 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001844 auto displayFrame1 = getDisplayFrame(0);
1845 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1846 presentFence1->signalForTest(30);
1847
1848 // Fences for the first frame haven't been flushed yet, so it should be 0
1849 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1850 auto actuals1 = presentedSurfaceFrame1.getActuals();
1851 EXPECT_EQ(actuals1.presentTime, 0);
1852
1853 // Trigger a flush by finalizing the next DisplayFrame
1854 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08001855 FrameTimelineInfo ftInfo2;
1856 ftInfo2.vsyncId = surfaceFrameToken2;
1857 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001858 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001859 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1860 sLayerNameOne, sLayerNameOne,
1861 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001862 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001863 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001864 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1865 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001866 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001867 auto displayFrame2 = getDisplayFrame(1);
1868 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1869
1870 // Fences for the first frame have flushed, so the present timestamps should be updated
1871 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1872 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1873 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1874 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1875
1876 actuals1 = presentedSurfaceFrame1.getActuals();
1877 EXPECT_EQ(actuals1.presentTime, 30);
1878 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1879 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1880 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1881
1882 // Fences for the second frame haven't been flushed yet, so it should be 0
1883 presentFence2->signalForTest(65);
1884 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1885 auto actuals2 = presentedSurfaceFrame2.getActuals();
1886 EXPECT_EQ(actuals2.presentTime, 0);
1887
Alec Mouri363faf02021-01-29 16:34:55 -08001888 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1889
1890 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001891 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
1892 sLayerNameOne, sGameMode,
1893 JankType::PredictionError, -3, 5,
1894 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08001895
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001896 addEmptyDisplayFrame();
1897
1898 // Fences for the second frame have flushed, so the present timestamps should be updated
1899 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1900 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1901 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1902 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1903
1904 actuals2 = presentedSurfaceFrame2.getActuals();
1905 EXPECT_EQ(actuals2.presentTime, 65);
1906 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1907 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1908 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1909}
1910
1911TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001912 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001913 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001914 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1915 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001916 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1917 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08001918 FrameTimelineInfo ftInfo;
1919 ftInfo.vsyncId = surfaceFrameToken1;
1920 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001921 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001922 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1923 sLayerNameOne, sLayerNameOne,
1924 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001925 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001926 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001927 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1928 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1929 mFrameTimeline->setSfPresent(26, presentFence1);
1930 auto displayFrame1 = getDisplayFrame(0);
1931 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1932 presentFence1->signalForTest(50);
1933
1934 // Fences for the first frame haven't been flushed yet, so it should be 0
1935 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1936 auto actuals1 = presentedSurfaceFrame1.getActuals();
1937 EXPECT_EQ(actuals1.presentTime, 0);
1938
1939 // Trigger a flush by finalizing the next DisplayFrame
1940 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08001941 FrameTimelineInfo ftInfo2;
1942 ftInfo2.vsyncId = surfaceFrameToken2;
1943 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001944 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001945 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1946 sLayerNameOne, sLayerNameOne,
1947 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001948 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001949 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001950 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1951 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001952 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001953 auto displayFrame2 = getDisplayFrame(1);
1954 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1955
1956 // Fences for the first frame have flushed, so the present timestamps should be updated
1957 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1958 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1959 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1960 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1961
1962 actuals1 = presentedSurfaceFrame1.getActuals();
1963 EXPECT_EQ(actuals1.presentTime, 50);
1964 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1965 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1966 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1967
1968 // Fences for the second frame haven't been flushed yet, so it should be 0
1969 presentFence2->signalForTest(86);
1970 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1971 auto actuals2 = presentedSurfaceFrame2.getActuals();
1972 EXPECT_EQ(actuals2.presentTime, 0);
1973
Alec Mouri363faf02021-01-29 16:34:55 -08001974 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1975
1976 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001977 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
1978 sLayerNameOne, sGameMode,
1979 JankType::PredictionError, -3, 5,
1980 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08001981
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001982 addEmptyDisplayFrame();
1983
1984 // Fences for the second frame have flushed, so the present timestamps should be updated
1985 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1986 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1987 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1988 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1989
1990 actuals2 = presentedSurfaceFrame2.getActuals();
1991 EXPECT_EQ(actuals2.presentTime, 86);
1992 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1993 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1994 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1995}
1996
1997TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001998 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08001999
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002000 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002001 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002002 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -08002003 FrameTimelineInfo ftInfo;
2004 ftInfo.vsyncId = surfaceFrameToken1;
2005 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002006 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002007 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2008 sLayerNameOne, sLayerNameOne,
2009 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002010 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002011 mFrameTimeline->setSfWakeUp(sfToken1, 42, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002012 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2013 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2014 mFrameTimeline->setSfPresent(46, presentFence1);
2015 auto displayFrame1 = getDisplayFrame(0);
2016 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2017 presentFence1->signalForTest(50);
2018
2019 // Fences for the first frame haven't been flushed yet, so it should be 0
2020 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2021 auto actuals1 = presentedSurfaceFrame1.getActuals();
2022 EXPECT_EQ(actuals1.presentTime, 0);
2023
2024 addEmptyDisplayFrame();
2025
2026 // Fences for the first frame have flushed, so the present timestamps should be updated
2027 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
2028 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2029 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2030 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2031
2032 actuals1 = presentedSurfaceFrame1.getActuals();
2033 EXPECT_EQ(actuals1.presentTime, 50);
2034 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2035 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2036 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
2037}
2038
2039TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002040 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as only
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002041 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002042 // jank to the SurfaceFrame along with AppDeadlineMissed.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002043
Alec Mouri363faf02021-01-29 16:34:55 -08002044 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002045 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002046 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
2047 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002048 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
2049 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
Huihong Luo3bdef862022-03-03 11:57:19 -08002050 FrameTimelineInfo ftInfo;
2051 ftInfo.vsyncId = surfaceFrameToken1;
2052 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002053 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002054 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2055 sLayerNameOne, sLayerNameOne,
2056 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002057 surfaceFrame1->setAcquireFenceTime(26);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002058 mFrameTimeline->setSfWakeUp(sfToken1, 32, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002059 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2060 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2061 mFrameTimeline->setSfPresent(36, presentFence1);
2062 auto displayFrame1 = getDisplayFrame(0);
2063 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2064 presentFence1->signalForTest(40);
2065
2066 // Fences for the first frame haven't been flushed yet, so it should be 0
2067 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2068 auto actuals1 = presentedSurfaceFrame1.getActuals();
2069 EXPECT_EQ(actuals1.presentTime, 0);
2070
2071 // Trigger a flush by finalizing the next DisplayFrame
2072 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002073 FrameTimelineInfo ftInfo2;
2074 ftInfo2.vsyncId = surfaceFrameToken2;
2075 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002076 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002077 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2078 sLayerNameOne, sLayerNameOne,
2079 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002080 surfaceFrame2->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002081 mFrameTimeline->setSfWakeUp(sfToken2, 43, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002082 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2083 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2084 mFrameTimeline->setSfPresent(56, presentFence2);
2085 auto displayFrame2 = getDisplayFrame(1);
2086 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2087
2088 // Fences for the first frame have flushed, so the present timestamps should be updated
2089 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
2090 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2091 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2092 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2093
2094 actuals1 = presentedSurfaceFrame1.getActuals();
2095 EXPECT_EQ(actuals1.presentTime, 40);
2096 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2097 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2098 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2099
2100 // Fences for the second frame haven't been flushed yet, so it should be 0
2101 presentFence2->signalForTest(60);
2102 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2103 auto actuals2 = presentedSurfaceFrame2.getActuals();
2104 EXPECT_EQ(actuals2.presentTime, 0);
2105
2106 addEmptyDisplayFrame();
2107
2108 // Fences for the second frame have flushed, so the present timestamps should be updated
2109 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
2110 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2111 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2112 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
2113
2114 actuals2 = presentedSurfaceFrame2.getActuals();
2115 EXPECT_EQ(actuals2.presentTime, 60);
2116 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2117 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002118 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2119 JankType::SurfaceFlingerCpuDeadlineMissed | JankType::AppDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002120}
2121
2122TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002123 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08002124 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002125 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2126 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2127 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2128
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002129 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2130 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Huihong Luo3bdef862022-03-03 11:57:19 -08002131 FrameTimelineInfo ftInfo;
2132 ftInfo.vsyncId = surfaceFrameToken1;
2133 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002134 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002135 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2136 sLayerNameOne, sLayerNameOne,
2137 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002138 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002139 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002140 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2141 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2142 mFrameTimeline->setSfPresent(56, presentFence1);
2143 auto displayFrame1 = getDisplayFrame(0);
2144 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2145 presentFence1->signalForTest(60);
2146
2147 // Fences for the first frame haven't been flushed yet, so it should be 0
2148 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2149 auto actuals1 = presentedSurfaceFrame1.getActuals();
2150 EXPECT_EQ(actuals1.presentTime, 0);
2151
2152 // Trigger a flush by finalizing the next DisplayFrame
2153 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002154 FrameTimelineInfo ftInfo2;
2155 ftInfo2.vsyncId = surfaceFrameToken2;
2156 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002157 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002158 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2159 sLayerNameOne, sLayerNameOne,
2160 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002161 surfaceFrame2->setAcquireFenceTime(84);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002162 mFrameTimeline->setSfWakeUp(sfToken2, 112, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002163 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2164 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2165 mFrameTimeline->setSfPresent(116, presentFence2);
2166 auto displayFrame2 = getDisplayFrame(1);
2167 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2168 presentFence2->signalForTest(120);
2169
2170 // Fences for the first frame have flushed, so the present timestamps should be updated
2171 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2172 actuals1 = presentedSurfaceFrame1.getActuals();
2173 EXPECT_EQ(actuals1.endTime, 50);
2174 EXPECT_EQ(actuals1.presentTime, 60);
2175
2176 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2177 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2178 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2179
2180 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2181 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2182 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2183
2184 // Fences for the second frame haven't been flushed yet, so it should be 0
2185 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2186 auto actuals2 = presentedSurfaceFrame2.getActuals();
2187 EXPECT_EQ(actuals2.presentTime, 0);
2188
2189 addEmptyDisplayFrame();
2190
2191 // Fences for the second frame have flushed, so the present timestamps should be updated
2192 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
2193 actuals2 = presentedSurfaceFrame2.getActuals();
2194 EXPECT_EQ(actuals2.presentTime, 120);
2195
2196 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2197 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2198 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
2199
2200 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2201 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2202 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2203 JankType::AppDeadlineMissed | JankType::BufferStuffing);
2204}
Alec Mouriadebf5c2021-01-05 12:57:36 -08002205
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002206TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
2207 // Layer specific increment
2208 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
2209 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2210 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2211 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2212
2213 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2214 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -08002215 FrameTimelineInfo ftInfo;
2216 ftInfo.vsyncId = surfaceFrameToken1;
2217 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002218 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002219 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2220 sLayerNameOne, sLayerNameOne,
2221 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002222 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002223 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002224 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2225 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2226 mFrameTimeline->setSfPresent(56, presentFence1);
2227 auto displayFrame1 = getDisplayFrame(0);
2228 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2229 presentFence1->signalForTest(60);
2230
2231 // Fences for the first frame haven't been flushed yet, so it should be 0
2232 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2233 auto actuals1 = presentedSurfaceFrame1.getActuals();
2234 EXPECT_EQ(actuals1.presentTime, 0);
2235
2236 // Trigger a flush by finalizing the next DisplayFrame
2237 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002238 FrameTimelineInfo ftInfo2;
2239 ftInfo2.vsyncId = surfaceFrameToken2;
2240 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002241 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002242 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2243 sLayerNameOne, sLayerNameOne,
2244 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002245 surfaceFrame2->setAcquireFenceTime(80);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002246 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002247 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
2248 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2249 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2250 mFrameTimeline->setSfPresent(86, presentFence2);
2251 auto displayFrame2 = getDisplayFrame(1);
2252 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2253 presentFence2->signalForTest(90);
2254
2255 // Fences for the first frame have flushed, so the present timestamps should be updated
2256 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2257 actuals1 = presentedSurfaceFrame1.getActuals();
2258 EXPECT_EQ(actuals1.endTime, 50);
2259 EXPECT_EQ(actuals1.presentTime, 60);
2260
2261 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2262 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2263 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2264
2265 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2266 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2267 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2268
2269 // Fences for the second frame haven't been flushed yet, so it should be 0
2270 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2271 auto actuals2 = presentedSurfaceFrame2.getActuals();
2272 EXPECT_EQ(actuals2.presentTime, 0);
2273
2274 addEmptyDisplayFrame();
2275
2276 // Fences for the second frame have flushed, so the present timestamps should be updated
2277 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2278 actuals2 = presentedSurfaceFrame2.getActuals();
2279 EXPECT_EQ(actuals2.presentTime, 90);
2280
2281 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2282 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2283 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
2284
2285 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2286 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2287 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
2288}
2289
Rachel Lee94917b32022-03-18 17:52:09 -07002290TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent_GpuAndCpuMiss) {
2291 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2292 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2293 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2294 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2295 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2296
2297 // Case 1: cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002298 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Rachel Lee94917b32022-03-18 17:52:09 -07002299 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
2300 auto displayFrame = getDisplayFrame(0);
2301 gpuFence1->signalForTest(36);
2302 presentFence1->signalForTest(52);
2303
2304 // Fences haven't been flushed yet, so it should be 0
2305 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
2306
2307 addEmptyDisplayFrame();
2308 displayFrame = getDisplayFrame(0);
2309
2310 // Fences have flushed, so the present timestamps should be updated
2311 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
2312 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2313 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2314 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
2315
2316 // Case 2: No GPU fence so it will not use GPU composition.
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002317 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Rachel Lee94917b32022-03-18 17:52:09 -07002318 mFrameTimeline->setSfPresent(66, presentFence2);
2319 auto displayFrame2 = getDisplayFrame(2); // 2 because of previous empty frame
2320 presentFence2->signalForTest(90);
2321
2322 // Fences for the frame haven't been flushed yet, so it should be 0
2323 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2324
2325 addEmptyDisplayFrame();
2326
2327 // Fences have flushed, so the present timestamps should be updated
2328 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2329 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2330 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2331 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
2332}
2333
Ady Abrahamfcb16862022-10-10 14:35:21 -07002334TEST_F(FrameTimelineTest, jankClassification_presentFenceError) {
2335 auto erroneousPresentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2336 auto erroneousPresentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2337 auto validPresentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2338 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2339 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2340 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({72, 80, 80});
2341
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002342 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002343 mFrameTimeline->setSfPresent(26, erroneousPresentFence1);
2344
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002345 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002346 mFrameTimeline->setSfPresent(60, erroneousPresentFence2);
2347
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002348 mFrameTimeline->setSfWakeUp(sfToken3, 72, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002349 mFrameTimeline->setSfPresent(80, validPresentFence);
2350
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002351 erroneousPresentFence2->signalForTest(2);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002352 validPresentFence->signalForTest(80);
2353
2354 addEmptyDisplayFrame();
2355
2356 {
2357 auto displayFrame = getDisplayFrame(0);
2358 EXPECT_EQ(displayFrame->getActuals().presentTime, 26);
2359 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2360 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002361 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002362 }
2363 {
2364 auto displayFrame = getDisplayFrame(1);
2365 EXPECT_EQ(displayFrame->getActuals().presentTime, 60);
2366 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2367 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002368 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002369 }
2370 {
2371 auto displayFrame = getDisplayFrame(2);
2372 EXPECT_EQ(displayFrame->getActuals().presentTime, 80);
2373 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2374 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2375 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
2376 }
2377}
2378
Alec Mouriadebf5c2021-01-05 12:57:36 -08002379TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
2380 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
2381}
2382
2383TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002384 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002385
2386 auto surfaceFrame1 =
2387 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002388 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002389 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002390 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2391 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2392 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2393 presentFence1->signalForTest(oneHundredMs);
2394 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2395
2396 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2397}
2398
2399TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002400 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2401 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002402 auto surfaceFrame1 =
2403 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002404 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002405 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002406 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2407 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2408 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2409 presentFence1->signalForTest(oneHundredMs);
2410 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2411
2412 auto surfaceFrame2 =
2413 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002414 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002415 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002416 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2417 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2418 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2419 presentFence2->signalForTest(twoHundredMs);
2420 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2421
2422 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
2423}
2424
2425TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002426 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2427 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002428 auto surfaceFrame1 =
2429 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002430 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002431 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002432 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2433 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2434 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2435 presentFence1->signalForTest(oneHundredMs);
2436 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2437
2438 auto surfaceFrame2 =
2439 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002440 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002441 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002442 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2443 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2444 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2445 presentFence2->signalForTest(twoHundredMs);
2446 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2447
2448 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
2449}
2450
2451TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002452 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2453 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002454 auto surfaceFrame1 =
2455 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002456 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002457 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002458 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2459 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2460 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2461 presentFence1->signalForTest(oneHundredMs);
2462 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2463
2464 auto surfaceFrame2 =
2465 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002466 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002467 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002468 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2469 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2470 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2471 presentFence2->signalForTest(twoHundredMs);
2472 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2473
2474 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2475}
2476
2477TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002478 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2479 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2480 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2481 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2482 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002483 auto surfaceFrame1 =
2484 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002485 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002486 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002487 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2488 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2489 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2490 presentFence1->signalForTest(oneHundredMs);
2491 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2492
2493 auto surfaceFrame2 =
2494 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002495 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002496 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002497 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2498 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2499 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2500 presentFence2->signalForTest(twoHundredMs);
2501 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2502
2503 auto surfaceFrame3 =
2504 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002505 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002506 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002507 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2508 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2509 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2510 presentFence3->signalForTest(threeHundredMs);
2511 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2512
2513 auto surfaceFrame4 =
2514 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002515 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002516 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002517 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2518 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2519 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2520 presentFence4->signalForTest(fiveHundredMs);
2521 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2522
2523 auto surfaceFrame5 =
2524 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002525 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002526 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002527 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2528 // Dropped frames will be excluded from fps computation
2529 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2530 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2531 presentFence5->signalForTest(sixHundredMs);
2532 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2533
2534 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2535}
2536
ramindaniea2bb822022-06-27 19:52:10 +00002537TEST_F(FrameTimelineTest, getMinTime) {
2538 // Use SurfaceFrame::getBaseTime to test the getMinTime.
2539 FrameTimelineInfo ftInfo;
2540
2541 // Valid prediction state test.
2542 ftInfo.vsyncId = 0L;
2543 mTokenManager->generateTokenForPredictions({10});
2544 auto surfaceFrame =
2545 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2546 sLayerNameOne, sLayerNameOne,
2547 /*isBuffer*/ true, sGameMode);
2548 ASSERT_EQ(surfaceFrame->getBaseTime(), 10);
2549
2550 // Test prediction state which is not valid.
2551 ftInfo.vsyncId = FrameTimelineInfo::INVALID_VSYNC_ID;
2552 surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2553 sLayerNameOne, sLayerNameOne,
2554 /*isBuffer*/ true, sGameMode);
2555 // Start time test.
2556 surfaceFrame->setActualStartTime(200);
2557 ASSERT_EQ(surfaceFrame->getBaseTime(), 200);
2558
2559 // End time test.
2560 surfaceFrame->setAcquireFenceTime(100);
2561 ASSERT_EQ(surfaceFrame->getBaseTime(), 100);
2562
2563 // Present time test.
2564 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2565 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2566 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2567 presentFence->signalForTest(std::chrono::nanoseconds(50ns).count());
2568 mFrameTimeline->setSfPresent(50, presentFence);
2569 ASSERT_EQ(surfaceFrame->getBaseTime(), 50);
2570}
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002571
2572TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingDisplayRate) {
2573 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2574 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2575 FrameTimelineInfo ftInfo;
2576 ftInfo.vsyncId = token1;
2577 ftInfo.inputEventId = sInputEventId;
2578 auto surfaceFrame =
2579 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2580 sLayerNameOne, sLayerNameOne,
2581 /*isBuffer*/ true, sGameMode);
2582
2583 mFrameTimeline->setSfWakeUp(token1, 20, RR_30, RR_11);
2584 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2585 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2586 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2587 mFrameTimeline->setSfPresent(50, presentFence1);
2588
2589 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 11);
2590}
2591
2592TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingAppFrameRate) {
2593 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2594 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2595 FrameTimelineInfo ftInfo;
2596 ftInfo.vsyncId = token1;
2597 ftInfo.inputEventId = sInputEventId;
2598 auto surfaceFrame =
2599 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2600 sLayerNameOne, sLayerNameOne,
2601 /*isBuffer*/ true, sGameMode);
2602 surfaceFrame->setRenderRate(RR_30);
2603 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
2604 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2605 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2606 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2607 mFrameTimeline->setSfPresent(50, presentFence1);
2608
2609 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 30);
2610}
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002611} // namespace android::frametimeline