blob: fae236dfbbb6c5cd12bd764cd26ff9f368f9d1a1 [file] [log] [blame]
Adithya Srinivasanf279e042020-08-17 14:56:27 -07001/*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Ady Abraham3db8a3c2023-11-20 17:53:47 -080017#include <common/test/FlagUtils.h>
Sally Qif5721252023-11-17 11:14:53 -080018#include "com_android_graphics_surfaceflinger_flags.h"
Alec Mouri9a29e672020-09-14 12:39:14 -070019#include "gmock/gmock-spec-builders.h"
20#include "mock/MockTimeStats.h"
Adithya Srinivasanf279e042020-08-17 14:56:27 -070021#undef LOG_TAG
22#define LOG_TAG "LibSurfaceFlingerUnittests"
23
24#include <FrameTimeline/FrameTimeline.h>
25#include <gtest/gtest.h>
26#include <log/log.h>
Adithya Srinivasan01189672020-10-20 14:23:05 -070027#include <perfetto/trace/trace.pb.h>
Adithya Srinivasanf279e042020-08-17 14:56:27 -070028#include <cinttypes>
29
30using namespace std::chrono_literals;
Alec Mouri363faf02021-01-29 16:34:55 -080031using testing::_;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -080032using testing::AtLeast;
Alec Mouri9a29e672020-09-14 12:39:14 -070033using testing::Contains;
Adithya Srinivasan01189672020-10-20 14:23:05 -070034using FrameTimelineEvent = perfetto::protos::FrameTimelineEvent;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000035using ProtoExpectedDisplayFrameStart =
36 perfetto::protos::FrameTimelineEvent_ExpectedDisplayFrameStart;
37using ProtoExpectedSurfaceFrameStart =
38 perfetto::protos::FrameTimelineEvent_ExpectedSurfaceFrameStart;
39using ProtoActualDisplayFrameStart = perfetto::protos::FrameTimelineEvent_ActualDisplayFrameStart;
40using ProtoActualSurfaceFrameStart = perfetto::protos::FrameTimelineEvent_ActualSurfaceFrameStart;
41using ProtoFrameEnd = perfetto::protos::FrameTimelineEvent_FrameEnd;
Adithya Srinivasan01189672020-10-20 14:23:05 -070042using ProtoPresentType = perfetto::protos::FrameTimelineEvent_PresentType;
43using ProtoJankType = perfetto::protos::FrameTimelineEvent_JankType;
Ying Wei96eb5352023-11-21 17:37:21 +000044using ProtoJankSeverityType = perfetto::protos::FrameTimelineEvent_JankSeverityType;
Adithya Srinivasan78e58af2021-02-25 00:08:08 +000045using ProtoPredictionType = perfetto::protos::FrameTimelineEvent_PredictionType;
Alec Mouri9a29e672020-09-14 12:39:14 -070046
Adithya Srinivasanf279e042020-08-17 14:56:27 -070047namespace android::frametimeline {
48
Ady Abraham57a8ab42023-01-26 15:28:19 -080049static const std::string sLayerNameOne = "layer1";
50static const std::string sLayerNameTwo = "layer2";
51
52constexpr const uid_t sUidOne = 0;
53constexpr pid_t sPidOne = 10;
54constexpr pid_t sPidTwo = 20;
55constexpr int32_t sInputEventId = 5;
56constexpr int32_t sLayerIdOne = 1;
57constexpr int32_t sLayerIdTwo = 2;
58constexpr GameMode sGameMode = GameMode::Unsupported;
Pascal Muetschardac7bcd92023-10-03 15:05:36 +020059constexpr Fps RR_11 = Fps::fromPeriodNsecs(11);
60constexpr Fps RR_30 = Fps::fromPeriodNsecs(30);
Ady Abraham57a8ab42023-01-26 15:28:19 -080061
Adithya Srinivasanf279e042020-08-17 14:56:27 -070062class FrameTimelineTest : public testing::Test {
63public:
64 FrameTimelineTest() {
65 const ::testing::TestInfo* const test_info =
66 ::testing::UnitTest::GetInstance()->current_test_info();
67 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
68 }
69
70 ~FrameTimelineTest() {
71 const ::testing::TestInfo* const test_info =
72 ::testing::UnitTest::GetInstance()->current_test_info();
73 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
74 }
75
Adithya Srinivasan01189672020-10-20 14:23:05 -070076 static void SetUpTestSuite() {
77 // Need to initialize tracing in process for testing, and only once per test suite.
78 perfetto::TracingInitArgs args;
79 args.backends = perfetto::kInProcessBackend;
80 perfetto::Tracing::Initialize(args);
81 }
82
Adithya Srinivasanf279e042020-08-17 14:56:27 -070083 void SetUp() override {
Ady Abraham57f8e182022-03-08 15:54:33 -080084 constexpr bool kUseBootTimeClock = true;
Alec Mouri9a29e672020-09-14 12:39:14 -070085 mTimeStats = std::make_shared<mock::TimeStats>();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000086 mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats, kSurfaceFlingerPid,
Ady Abraham57f8e182022-03-08 15:54:33 -080087 kTestThresholds, !kUseBootTimeClock);
Adithya Srinivasan01189672020-10-20 14:23:05 -070088 mFrameTimeline->registerDataSource();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070089 mTokenManager = &mFrameTimeline->mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000090 mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
Adithya Srinivasan2d736322020-10-01 16:53:48 -070091 maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +000092 maxTokens = mTokenManager->kMaxTokens;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070093 }
94
Adithya Srinivasan01189672020-10-20 14:23:05 -070095 // Each tracing session can be used for a single block of Start -> Stop.
96 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
97 perfetto::TraceConfig cfg;
98 cfg.set_duration_ms(500);
99 cfg.add_buffers()->set_size_kb(1024);
100 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
101 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
102
103 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
104 tracingSession->Setup(cfg);
105 return tracingSession;
106 }
107
108 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
109 perfetto::TracingSession* tracingSession) {
110 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
111 perfetto::protos::Trace trace;
112 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
113
114 std::vector<perfetto::protos::TracePacket> packets;
115 for (const auto& packet : trace.packet()) {
116 if (!packet.has_frame_timeline_event()) {
117 continue;
118 }
119 packets.emplace_back(packet);
120 }
121 return packets;
122 }
123
Ady Abraham57a8ab42023-01-26 15:28:19 -0800124 void addEmptySurfaceFrame() {
125 auto surfaceFrame =
126 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
127 sLayerNameOne, sLayerNameOne,
128 /*isBuffer*/ false, sGameMode);
129 mFrameTimeline->addSurfaceFrame(std::move(surfaceFrame));
130 }
131
Adithya Srinivasan01189672020-10-20 14:23:05 -0700132 void addEmptyDisplayFrame() {
133 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000134 // Trigger a flushPresentFence by calling setSfPresent for the next frame
Adithya Srinivasan01189672020-10-20 14:23:05 -0700135 mFrameTimeline->setSfPresent(2500, presentFence1);
136 }
137
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000138 void flushTokens() {
139 for (size_t i = 0; i < maxTokens; i++) {
140 mTokenManager->generateTokenForPredictions({});
141 }
142 EXPECT_EQ(getPredictions().size(), maxTokens);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700143 }
144
145 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
146 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800147 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
148 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700149 }
150
151 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
152 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
153 return mFrameTimeline->mDisplayFrames[idx];
154 }
155
156 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
157 return a.startTime == b.startTime && a.endTime == b.endTime &&
158 a.presentTime == b.presentTime;
159 }
160
Liz Prucka31b58c92024-11-08 21:13:44 +0000161 NO_THREAD_SAFETY_ANALYSIS
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000162 const std::map<int64_t, TimelineItem>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700163 return mTokenManager->mPredictions;
164 }
165
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000166 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700167 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
168 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
169 }
170
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000171 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
172
173 void flushTrace() {
174 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
175 FrameTimelineDataSource::Trace(
176 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
177 }
178
Alec Mouri9a29e672020-09-14 12:39:14 -0700179 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700180 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
181 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000182 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700183 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700184 uint32_t* maxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000185 size_t maxTokens;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000186 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasanead17162021-02-18 02:17:37 +0000187 static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan54996e22021-06-25 22:26:45 +0000188 static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(0ns).count();
Adithya Srinivasanead17162021-02-18 02:17:37 +0000189 static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800190 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
191 kDeadlineThreshold,
192 kStartThreshold};
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700193};
194
195TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
196 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000197 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000198 flushTokens();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700199 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
200 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
201
202 // token1 should have expired
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700203 EXPECT_EQ(predictions.has_value(), false);
204
205 predictions = mTokenManager->getPredictionsForToken(token2);
206 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
207}
208
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700209TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800210 auto surfaceFrame1 =
211 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000212 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000213 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -0800214 auto surfaceFrame2 =
215 mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000216 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000217 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700218 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
219 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
220}
221
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700222TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800223 auto surfaceFrame =
224 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000225 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000226 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700227 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
228}
229
230TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
231 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000232 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -0800233 FrameTimelineInfo ftInfo;
234 ftInfo.vsyncId = token1;
235 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000236 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800237 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
238 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000239 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700240
241 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
242}
243
244TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
245 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800246 FrameTimelineInfo ftInfo;
247 ftInfo.vsyncId = token1;
248 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000249 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800250 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
251 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000252 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700253
254 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
255 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
256}
257
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000258TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
259 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
260 constexpr int32_t inputEventId = 1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800261 FrameTimelineInfo ftInfo;
262 ftInfo.vsyncId = token1;
263 ftInfo.inputEventId = inputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000264 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800265 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
266 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000267 /*isBuffer*/ true, sGameMode);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000268
269 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
270}
271
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700272TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
273 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700274 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800275 FrameTimelineInfo ftInfo;
276 ftInfo.vsyncId = token1;
277 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000278 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800279 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
280 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000281 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700282
283 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200284 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000285 surfaceFrame1->setDropTime(12);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800286 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
287 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700288 mFrameTimeline->setSfPresent(25, presentFence1);
289 presentFence1->signalForTest(30);
290
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000291 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700292
293 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
294 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000295 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
296 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700297 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
298}
299
300TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800301 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800302 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700303 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
304 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700305 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800306 FrameTimelineInfo ftInfo;
307 ftInfo.vsyncId = surfaceFrameToken1;
308 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700309 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800310 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
311 sLayerNameOne, sLayerNameOne,
312 /*isBuffer*/ true, sGameMode);
Alec Mouri9a29e672020-09-14 12:39:14 -0700313 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800314 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdTwo,
315 sLayerNameTwo, sLayerNameTwo,
316 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200317 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800318 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
319 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
320 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
321 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700322 mFrameTimeline->setSfPresent(26, presentFence1);
323 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800324 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
325 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700326 presentFence1->signalForTest(42);
327
328 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800329 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700330 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
331 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
332
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000333 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700334
335 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800336 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700337 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
338 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100339 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
Ying Wei96eb5352023-11-21 17:37:21 +0000340 EXPECT_NE(surfaceFrame1->getJankSeverityType(), std::nullopt);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100341 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Ying Wei96eb5352023-11-21 17:37:21 +0000342 EXPECT_NE(surfaceFrame2->getJankSeverityType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700343}
344
Ady Abraham14beed72024-05-15 17:16:45 -0700345TEST_F(FrameTimelineTest, displayFrameSkippedComposition) {
346 // Layer specific increment
347 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(1);
348 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
349 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
350 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
351 FrameTimelineInfo ftInfo;
352 ftInfo.vsyncId = surfaceFrameToken1;
353 ftInfo.inputEventId = sInputEventId;
354 auto surfaceFrame1 =
355 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
356 sLayerNameOne, sLayerNameOne,
357 /*isBuffer*/ true, sGameMode);
358 auto surfaceFrame2 =
359 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdTwo,
360 sLayerNameTwo, sLayerNameTwo,
361 /*isBuffer*/ true, sGameMode);
362
363 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
364 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
365 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
366 mFrameTimeline->onCommitNotComposited();
367
368 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 30);
369 ASSERT_NE(surfaceFrame1->getJankType(), std::nullopt);
370 EXPECT_EQ(*surfaceFrame1->getJankType(), JankType::None);
371 ASSERT_NE(surfaceFrame1->getJankSeverityType(), std::nullopt);
372 EXPECT_EQ(*surfaceFrame1->getJankSeverityType(), JankSeverityType::None);
373
374 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
375 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
376 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
377 mFrameTimeline->setSfPresent(26, presentFence1);
378
379 auto displayFrame = getDisplayFrame(0);
380 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 0);
381 presentFence1->signalForTest(42);
382
383 // Fences haven't been flushed yet, so it should be 0
384 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
385 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
386
387 addEmptyDisplayFrame();
388
389 // Fences have flushed, so the present timestamps should be updated
390 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
391 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
392 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
393 EXPECT_NE(surfaceFrame2->getJankSeverityType(), std::nullopt);
394}
395
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700396TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
397 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
398 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800399 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800400 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800401 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700402 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700403 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
404 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
405 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
406 int64_t sfToken = mTokenManager->generateTokenForPredictions(
407 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800408 FrameTimelineInfo ftInfo;
409 ftInfo.vsyncId = surfaceFrameToken;
410 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700411 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800412 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000413 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000414 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200415 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800416 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
417 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700418 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
419 presentFence->signalForTest(32 + frameTimeFactor);
420 frameTimeFactor += 30;
421 }
422 auto displayFrame0 = getDisplayFrame(0);
423
424 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800425 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700426
427 // Add one more display frame
428 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
429 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
430 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
431 int64_t sfToken = mTokenManager->generateTokenForPredictions(
432 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800433 FrameTimelineInfo ftInfo;
434 ftInfo.vsyncId = surfaceFrameToken;
435 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700436 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800437 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
438 sLayerNameOne, sLayerNameOne,
439 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200440 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800441 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
442 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700443 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
444 presentFence->signalForTest(32 + frameTimeFactor);
445 displayFrame0 = getDisplayFrame(0);
446
447 // The window should have slided by 1 now and the previous 0th display frame
448 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800449 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700450}
451
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700452TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000453 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
454 "acquireFenceAfterQueue",
455 "acquireFenceAfterQueue",
456 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700457 surfaceFrame->setActualQueueTime(123);
458 surfaceFrame->setAcquireFenceTime(456);
459 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
460}
461
462TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000463 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
464 "acquireFenceAfterQueue",
465 "acquireFenceAfterQueue",
466 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700467 surfaceFrame->setActualQueueTime(456);
468 surfaceFrame->setAcquireFenceTime(123);
469 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
470}
471
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700472TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
473 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
474 presentFence->signalForTest(2);
475
476 // Size shouldn't exceed maxDisplayFrames - 64
477 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700478 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800479 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000480 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000481 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700482 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200483 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800484 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
485 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700486 mFrameTimeline->setSfPresent(27, presentFence);
487 }
488 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
489
490 // Increase the size to 256
491 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000492 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700493
494 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700495 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800496 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000497 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000498 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700499 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200500 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800501 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
502 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700503 mFrameTimeline->setSfPresent(27, presentFence);
504 }
505 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
506
507 // Shrink the size to 128
508 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000509 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700510
511 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700512 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800513 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000514 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000515 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700516 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200517 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800518 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
519 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700520 mFrameTimeline->setSfPresent(27, presentFence);
521 }
522 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
523}
Alec Mouri9a29e672020-09-14 12:39:14 -0700524
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000525TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200526 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000527
528 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
529 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
530 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800531 FrameTimelineInfo ftInfo;
532 ftInfo.vsyncId = surfaceFrameToken1;
533 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000534
535 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800536 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
537 sLayerNameOne, sLayerNameOne,
538 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200539 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000540 surfaceFrame1->setAcquireFenceTime(20);
541 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
542 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
543
544 mFrameTimeline->setSfPresent(59, presentFence1);
545 presentFence1->signalForTest(-1);
546 addEmptyDisplayFrame();
547
548 auto displayFrame0 = getDisplayFrame(0);
Ady Abrahamfcb16862022-10-10 14:35:21 -0700549 EXPECT_EQ(displayFrame0->getActuals().presentTime, 59);
Ady Abrahamb1e10d12023-03-13 15:23:54 -0700550 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +0000551 EXPECT_EQ(displayFrame0->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000552 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
553 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +0000554 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000555}
556
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800557// Tests related to TimeStats
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000558TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200559 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000560 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
561 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
562 int64_t surfaceFrameToken1 = -1;
563 int64_t sfToken1 = -1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800564 FrameTimelineInfo ftInfo;
565 ftInfo.vsyncId = surfaceFrameToken1;
566 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000567
568 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800569 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
570 sLayerNameOne, sLayerNameOne,
571 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200572 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000573 surfaceFrame1->setAcquireFenceTime(20);
574 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
575 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
576 presentFence1->signalForTest(70);
577
578 mFrameTimeline->setSfPresent(59, presentFence1);
579}
580
Alec Mouri9a29e672020-09-14 12:39:14 -0700581TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200582 Fps refreshRate = RR_11;
Alec Mouri9a29e672020-09-14 12:39:14 -0700583 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800584 incrementJankyFrames(
585 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000586 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000587 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800588 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700589 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000590 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
591 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800592 FrameTimelineInfo ftInfo;
593 ftInfo.vsyncId = surfaceFrameToken1;
594 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000595
Alec Mouri9a29e672020-09-14 12:39:14 -0700596 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800597 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
598 sLayerNameOne, sLayerNameOne,
599 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200600 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000601 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800602 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
603 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000604 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700605
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000606 mFrameTimeline->setSfPresent(62, presentFence1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700607}
608
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000609TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfGpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200610 Fps refreshRate = RR_11;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000611 EXPECT_CALL(*mTimeStats,
612 incrementJankyFrames(
613 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000614 sLayerNameOne, sGameMode,
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000615 JankType::SurfaceFlingerGpuDeadlineMissed, 4, 10,
616 0}));
617 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
618 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
619 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
620 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800621 FrameTimelineInfo ftInfo;
622 ftInfo.vsyncId = surfaceFrameToken1;
623 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000624
625 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800626 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
627 sLayerNameOne, sLayerNameOne,
628 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200629 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000630 surfaceFrame1->setAcquireFenceTime(20);
631 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
632 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
633 gpuFence1->signalForTest(64);
634 presentFence1->signalForTest(70);
635
636 mFrameTimeline->setSfPresent(59, presentFence1, gpuFence1);
637}
638
Alec Mouri9a29e672020-09-14 12:39:14 -0700639TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200640 Fps refreshRate = RR_30;
Alec Mouri9a29e672020-09-14 12:39:14 -0700641 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800642 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000643 sLayerNameOne, sGameMode,
644 JankType::DisplayHAL, -4, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800645
Alec Mouri9a29e672020-09-14 12:39:14 -0700646 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000647 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
648 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800649 FrameTimelineInfo ftInfo;
650 ftInfo.vsyncId = surfaceFrameToken1;
651 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000652
Alec Mouri9a29e672020-09-14 12:39:14 -0700653 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800654 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
655 sLayerNameOne, sLayerNameOne,
656 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200657 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800658 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000659 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800660 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000661 presentFence1->signalForTest(90);
662 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800663 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +0000664 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Alec Mouri9a29e672020-09-14 12:39:14 -0700665}
666
667TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700668 Fps refreshRate = 11_Hz;
Alec Mouri9a29e672020-09-14 12:39:14 -0700669 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000670 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000671 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000672 JankType::AppDeadlineMissed, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000673 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700674 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000675 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
676 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800677 FrameTimelineInfo ftInfo;
678 ftInfo.vsyncId = surfaceFrameToken1;
679 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000680
Alec Mouri9a29e672020-09-14 12:39:14 -0700681 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800682 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
683 sLayerNameOne, sLayerNameOne,
684 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000685 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200686 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700687
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800688 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
689 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000690 presentFence1->signalForTest(90);
691 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100692
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800693 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000694 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Partial);
Alec Mouri9a29e672020-09-14 12:39:14 -0700695}
696
Adithya Srinivasanead17162021-02-18 02:17:37 +0000697TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000698 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000699 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000700 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000701 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000702 JankType::SurfaceFlingerScheduling,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000703 -4, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000704 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000705 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
706 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800707 FrameTimelineInfo ftInfo;
708 ftInfo.vsyncId = surfaceFrameToken1;
709 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000710
Adithya Srinivasanead17162021-02-18 02:17:37 +0000711 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800712 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
713 sLayerNameOne, sLayerNameOne,
714 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000715 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200716 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000717
718 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
719 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000720 presentFence1->signalForTest(60);
721 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000722
723 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +0000724 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000725}
726
727TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000728 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000729 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000730 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000731 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000732 JankType::PredictionError, -4, 5,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000733 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000734 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000735 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
736 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800737 FrameTimelineInfo ftInfo;
738 ftInfo.vsyncId = surfaceFrameToken1;
739 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000740
Adithya Srinivasanead17162021-02-18 02:17:37 +0000741 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800742 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
743 sLayerNameOne, sLayerNameOne,
744 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000745 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200746 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000747
748 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
749 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000750 presentFence1->signalForTest(65);
751 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000752
753 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +0000754 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000755}
756
757TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000758 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000759 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000760 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000761 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000762 JankType::BufferStuffing, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000763 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000764 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000765 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
766 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800767 FrameTimelineInfo ftInfo;
768 ftInfo.vsyncId = surfaceFrameToken1;
769 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000770
Adithya Srinivasanead17162021-02-18 02:17:37 +0000771 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800772 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
773 sLayerNameOne, sLayerNameOne,
774 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000775 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200776 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000777
778 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000779 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000780 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000781 presentFence1->signalForTest(90);
782 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000783
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000784 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +0000785 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000786}
787
Alec Mouri363faf02021-01-29 16:34:55 -0800788TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200789 Fps refreshRate = RR_11;
790 Fps renderRate = RR_30;
Alec Mouri363faf02021-01-29 16:34:55 -0800791 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000792 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne,
793 sLayerNameOne, sGameMode,
794 JankType::AppDeadlineMissed, -4, 0,
795 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800796 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000797 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
798 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800799 FrameTimelineInfo ftInfo;
800 ftInfo.vsyncId = surfaceFrameToken1;
801 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000802
Alec Mouri363faf02021-01-29 16:34:55 -0800803 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800804 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
805 sLayerNameOne, sLayerNameOne,
806 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000807 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200808 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800809
810 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
811 surfaceFrame1->setRenderRate(renderRate);
812 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000813 presentFence1->signalForTest(90);
814 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800815
816 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000817 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Alec Mouri363faf02021-01-29 16:34:55 -0800818}
819
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000820TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200821 Fps refreshRate = RR_11;
822 Fps renderRate = RR_30;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000823
824 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000825 incrementJankyFrames(
826 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000827 sGameMode,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000828 JankType::Unknown | JankType::AppDeadlineMissed,
Adithya Srinivasande272452021-04-10 00:21:00 +0000829 0, 0, 25}));
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000830 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
831 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
832 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800833 FrameTimelineInfo ftInfo;
834 ftInfo.vsyncId = surfaceFrameToken1;
835 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000836
837 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800838 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
839 sLayerNameOne, sLayerNameOne,
840 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000841 surfaceFrame1->setAcquireFenceTime(45);
842 // Trigger a prediction expiry
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000843 flushTokens();
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200844 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000845
846 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
847 surfaceFrame1->setRenderRate(renderRate);
848 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
849 presentFence1->signalForTest(90);
850 mFrameTimeline->setSfPresent(86, presentFence1);
851
852 auto displayFrame = getDisplayFrame(0);
853 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +0000854 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000855 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
856 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
857 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
858
859 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000860 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +0000861 EXPECT_EQ(surfaceFrame1->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000862}
863
Adithya Srinivasan01189672020-10-20 14:23:05 -0700864/*
865 * Tracing Tests
866 *
867 * Trace packets are flushed all the way only when the next packet is traced.
868 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
869 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
870 * will have additional empty frames created for this reason.
871 */
872TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
873 auto tracingSession = getTracingSessionForTest();
874 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700875 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800876 FrameTimelineInfo ftInfo;
877 ftInfo.vsyncId = token1;
878 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000879 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800880 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
881 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000882 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700883
884 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200885 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800886 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
887 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700888 mFrameTimeline->setSfPresent(25, presentFence1);
889 presentFence1->signalForTest(30);
890
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000891 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700892
893 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000894 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700895}
896
897TEST_F(FrameTimelineTest, tracing_sanityTest) {
898 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800899 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800900 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700901 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700902
903 tracingSession->StartBlocking();
904 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
905 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800906 FrameTimelineInfo ftInfo;
907 ftInfo.vsyncId = token1;
908 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000909 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800910 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
911 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000912 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700913
914 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200915 mFrameTimeline->setSfWakeUp(token2, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800916 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
917 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700918 mFrameTimeline->setSfPresent(25, presentFence1);
919 presentFence1->signalForTest(30);
920
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000921 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000922 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700923 tracingSession->StopBlocking();
924
925 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000926 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000927 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700928}
929
930TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
931 auto tracingSession = getTracingSessionForTest();
932 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700933
934 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700935
936 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200937 mFrameTimeline->setSfWakeUp(-1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700938 mFrameTimeline->setSfPresent(25, presentFence1);
939 presentFence1->signalForTest(30);
940
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000941 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000942 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700943 tracingSession->StopBlocking();
944
945 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000946 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700947}
948
949TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
950 auto tracingSession = getTracingSessionForTest();
951 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700952
953 tracingSession->StartBlocking();
954 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -0800955 auto surfaceFrame1 =
956 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000957 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000958 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700959
960 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200961 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800962 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
963 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700964 mFrameTimeline->setSfPresent(25, presentFence1);
965 presentFence1->signalForTest(30);
966
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000967 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000968 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700969 tracingSession->StopBlocking();
970
971 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000972 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
973 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000974 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700975}
976
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000977ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
978 pid_t pid) {
979 ProtoExpectedDisplayFrameStart proto;
980 proto.set_cookie(cookie);
981 proto.set_token(token);
982 proto.set_pid(pid);
983 return proto;
984}
985
986ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
987 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Ying Wei96eb5352023-11-21 17:37:21 +0000988 bool gpuComposition, ProtoJankType jankType, ProtoJankSeverityType jankSeverityType,
989 ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000990 ProtoActualDisplayFrameStart proto;
991 proto.set_cookie(cookie);
992 proto.set_token(token);
993 proto.set_pid(pid);
994 proto.set_present_type(presentType);
995 proto.set_on_time_finish(onTimeFinish);
996 proto.set_gpu_composition(gpuComposition);
997 proto.set_jank_type(jankType);
Ying Wei96eb5352023-11-21 17:37:21 +0000998 proto.set_jank_severity_type(jankSeverityType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000999 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001000 return proto;
1001}
1002
1003ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
1004 int64_t displayFrameToken,
1005 pid_t pid,
1006 std::string layerName) {
1007 ProtoExpectedSurfaceFrameStart proto;
1008 proto.set_cookie(cookie);
1009 proto.set_token(token);
1010 proto.set_display_frame_token(displayFrameToken);
1011 proto.set_pid(pid);
1012 proto.set_layer_name(layerName);
1013 return proto;
1014}
1015
1016ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
1017 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
1018 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Ying Wei96eb5352023-11-21 17:37:21 +00001019 ProtoJankType jankType, ProtoJankSeverityType jankSeverityType,
1020 ProtoPredictionType predictionType, bool isBuffer) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001021 ProtoActualSurfaceFrameStart proto;
1022 proto.set_cookie(cookie);
1023 proto.set_token(token);
1024 proto.set_display_frame_token(displayFrameToken);
1025 proto.set_pid(pid);
1026 proto.set_layer_name(layerName);
1027 proto.set_present_type(presentType);
1028 proto.set_on_time_finish(onTimeFinish);
1029 proto.set_gpu_composition(gpuComposition);
1030 proto.set_jank_type(jankType);
Ying Wei96eb5352023-11-21 17:37:21 +00001031 proto.set_jank_severity_type(jankSeverityType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001032 proto.set_prediction_type(predictionType);
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001033 proto.set_is_buffer(isBuffer);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001034 return proto;
1035}
1036
1037ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
1038 ProtoFrameEnd proto;
1039 proto.set_cookie(cookie);
1040 return proto;
1041}
1042
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001043void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
1044 const ProtoExpectedDisplayFrameStart& source) {
1045 ASSERT_TRUE(received.has_cookie());
1046 EXPECT_EQ(received.cookie(), source.cookie());
1047
Adithya Srinivasan01189672020-10-20 14:23:05 -07001048 ASSERT_TRUE(received.has_token());
1049 EXPECT_EQ(received.token(), source.token());
1050
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001051 ASSERT_TRUE(received.has_pid());
1052 EXPECT_EQ(received.pid(), source.pid());
1053}
1054
1055void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
1056 const ProtoActualDisplayFrameStart& source) {
1057 ASSERT_TRUE(received.has_cookie());
1058 EXPECT_EQ(received.cookie(), source.cookie());
1059
1060 ASSERT_TRUE(received.has_token());
1061 EXPECT_EQ(received.token(), source.token());
1062
1063 ASSERT_TRUE(received.has_pid());
1064 EXPECT_EQ(received.pid(), source.pid());
1065
Adithya Srinivasan01189672020-10-20 14:23:05 -07001066 ASSERT_TRUE(received.has_present_type());
1067 EXPECT_EQ(received.present_type(), source.present_type());
1068 ASSERT_TRUE(received.has_on_time_finish());
1069 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1070 ASSERT_TRUE(received.has_gpu_composition());
1071 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1072 ASSERT_TRUE(received.has_jank_type());
1073 EXPECT_EQ(received.jank_type(), source.jank_type());
Ying Wei96eb5352023-11-21 17:37:21 +00001074 ASSERT_TRUE(received.has_jank_severity_type());
1075 EXPECT_EQ(received.jank_severity_type(), source.jank_severity_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001076 ASSERT_TRUE(received.has_prediction_type());
1077 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001078}
1079
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001080void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
1081 const ProtoExpectedSurfaceFrameStart& source) {
1082 ASSERT_TRUE(received.has_cookie());
1083 EXPECT_EQ(received.cookie(), source.cookie());
1084
Adithya Srinivasan01189672020-10-20 14:23:05 -07001085 ASSERT_TRUE(received.has_token());
1086 EXPECT_EQ(received.token(), source.token());
1087
1088 ASSERT_TRUE(received.has_display_frame_token());
1089 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1090
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001091 ASSERT_TRUE(received.has_pid());
1092 EXPECT_EQ(received.pid(), source.pid());
1093
1094 ASSERT_TRUE(received.has_layer_name());
1095 EXPECT_EQ(received.layer_name(), source.layer_name());
1096}
1097
1098void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
1099 const ProtoActualSurfaceFrameStart& source) {
1100 ASSERT_TRUE(received.has_cookie());
1101 EXPECT_EQ(received.cookie(), source.cookie());
1102
1103 ASSERT_TRUE(received.has_token());
1104 EXPECT_EQ(received.token(), source.token());
1105
1106 ASSERT_TRUE(received.has_display_frame_token());
1107 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1108
1109 ASSERT_TRUE(received.has_pid());
1110 EXPECT_EQ(received.pid(), source.pid());
1111
1112 ASSERT_TRUE(received.has_layer_name());
1113 EXPECT_EQ(received.layer_name(), source.layer_name());
1114
Adithya Srinivasan01189672020-10-20 14:23:05 -07001115 ASSERT_TRUE(received.has_present_type());
1116 EXPECT_EQ(received.present_type(), source.present_type());
1117 ASSERT_TRUE(received.has_on_time_finish());
1118 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1119 ASSERT_TRUE(received.has_gpu_composition());
1120 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1121 ASSERT_TRUE(received.has_jank_type());
1122 EXPECT_EQ(received.jank_type(), source.jank_type());
Ying Wei96eb5352023-11-21 17:37:21 +00001123 ASSERT_TRUE(received.has_jank_severity_type());
1124 EXPECT_EQ(received.jank_severity_type(), source.jank_severity_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001125 ASSERT_TRUE(received.has_prediction_type());
1126 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001127 ASSERT_TRUE(received.has_is_buffer());
1128 EXPECT_EQ(received.is_buffer(), source.is_buffer());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001129}
Adithya Srinivasan01189672020-10-20 14:23:05 -07001130
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001131void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
1132 ASSERT_TRUE(received.has_cookie());
1133 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001134}
1135
Sally Qi2269a692024-05-17 18:02:28 -07001136TEST_F(FrameTimelineTest, traceDisplayFrameNoSkipped) {
1137 // setup 2 display frames
1138 // DF 1: [22, 30] -> [0, 11]
1139 // DF 2: [82, 90] -> SF [5, 16]
1140 auto tracingSession = getTracingSessionForTest();
1141 tracingSession->StartBlocking();
1142 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1143 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 100});
1144 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({0, 11, 25});
1145 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1146 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1147
1148 int64_t traceCookie = snoopCurrentTraceCookie();
1149
1150 // set up 1st display frame
1151 FrameTimelineInfo ftInfo1;
1152 ftInfo1.vsyncId = surfaceFrameToken1;
1153 ftInfo1.inputEventId = sInputEventId;
1154 auto surfaceFrame1 =
1155 mFrameTimeline->createSurfaceFrameForToken(ftInfo1, sPidOne, sUidOne, sLayerIdOne,
1156 sLayerNameOne, sLayerNameOne,
1157 /*isBuffer*/ true, sGameMode);
1158 surfaceFrame1->setAcquireFenceTime(11);
1159 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_30);
1160 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1161 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1162 mFrameTimeline->setSfPresent(30, presentFence1);
1163 presentFence1->signalForTest(40);
1164
1165 // Trigger a flush by finalizing the next DisplayFrame
1166 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1167 FrameTimelineInfo ftInfo2;
1168 ftInfo2.vsyncId = surfaceFrameToken2;
1169 ftInfo2.inputEventId = sInputEventId;
1170 auto surfaceFrame2 =
1171 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1172 sLayerNameOne, sLayerNameOne,
1173 /*isBuffer*/ true, sGameMode);
1174
1175 // set up 2nd display frame
1176 surfaceFrame2->setAcquireFenceTime(16);
1177 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_11, RR_30);
1178 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1179 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1180 mFrameTimeline->setSfPresent(90, presentFence2);
1181 presentFence2->signalForTest(100);
1182
1183 // the token of skipped Display Frame
1184 auto protoSkippedActualDisplayFrameStart =
1185 createProtoActualDisplayFrameStart(traceCookie + 9, 0, kSurfaceFlingerPid,
1186 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1187 FrameTimelineEvent::JANK_DROPPED,
1188 FrameTimelineEvent::SEVERITY_NONE,
1189 FrameTimelineEvent::PREDICTION_VALID);
1190 auto protoSkippedActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 9);
1191
1192 // Trigger a flush by finalizing the next DisplayFrame
1193 addEmptyDisplayFrame();
1194 flushTrace();
1195 tracingSession->StopBlocking();
1196
1197 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1198 // 8 Valid Display Frames + 8 Valid Surface Frames + no Skipped Display Frames
1199 EXPECT_EQ(packets.size(), 16u);
1200}
1201
Sally Qiaa107742023-09-29 14:53:14 -07001202TEST_F(FrameTimelineTest, traceDisplayFrameSkipped) {
Sally Qif5721252023-11-17 11:14:53 -08001203 SET_FLAG_FOR_TEST(com::android::graphics::surfaceflinger::flags::add_sf_skipped_frames_to_trace,
1204 true);
1205
Sally Qiaa107742023-09-29 14:53:14 -07001206 // setup 2 display frames
1207 // DF 1: [22,40] -> [5, 40]
1208 // DF : [36, 70] (Skipped one, added by the trace)
1209 // DF 2: [82, 100] -> SF [25, 70]
1210 auto tracingSession = getTracingSessionForTest();
1211 tracingSession->StartBlocking();
1212 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1213 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 100});
1214 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1215 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1216 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1217
1218 int64_t traceCookie = snoopCurrentTraceCookie();
1219
1220 // set up 1st display frame
1221 FrameTimelineInfo ftInfo1;
1222 ftInfo1.vsyncId = surfaceFrameToken1;
1223 ftInfo1.inputEventId = sInputEventId;
1224 auto surfaceFrame1 =
1225 mFrameTimeline->createSurfaceFrameForToken(ftInfo1, sPidOne, sUidOne, sLayerIdOne,
1226 sLayerNameOne, sLayerNameOne,
1227 /*isBuffer*/ true, sGameMode);
1228 surfaceFrame1->setAcquireFenceTime(16);
1229 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_30);
1230 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1231 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1232 mFrameTimeline->setSfPresent(30, presentFence1);
1233 presentFence1->signalForTest(40);
1234
1235 // Trigger a flush by finalizing the next DisplayFrame
1236 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1237 FrameTimelineInfo ftInfo2;
1238 ftInfo2.vsyncId = surfaceFrameToken2;
1239 ftInfo2.inputEventId = sInputEventId;
1240 auto surfaceFrame2 =
1241 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1242 sLayerNameOne, sLayerNameOne,
1243 /*isBuffer*/ true, sGameMode);
1244
1245 // set up 2nd display frame
1246 surfaceFrame2->setAcquireFenceTime(36);
1247 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_11, RR_30);
1248 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1249 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1250 mFrameTimeline->setSfPresent(90, presentFence2);
1251 presentFence2->signalForTest(100);
1252
1253 // the token of skipped Display Frame
1254 auto protoSkippedActualDisplayFrameStart =
1255 createProtoActualDisplayFrameStart(traceCookie + 9, 0, kSurfaceFlingerPid,
1256 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1257 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001258 FrameTimelineEvent::SEVERITY_NONE,
Sally Qiaa107742023-09-29 14:53:14 -07001259 FrameTimelineEvent::PREDICTION_VALID);
1260 auto protoSkippedActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 9);
1261
1262 // Trigger a flush by finalizing the next DisplayFrame
1263 addEmptyDisplayFrame();
1264 flushTrace();
1265 tracingSession->StopBlocking();
1266
1267 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1268 // 8 Valid Display Frames + 8 Valid Surface Frames + 2 Skipped Display Frames
1269 EXPECT_EQ(packets.size(), 18u);
1270
1271 // Packet - 16: Actual skipped Display Frame Start
1272 // the timestamp should be equal to the 2nd expected surface frame's end time
1273 const auto& packet16 = packets[16];
1274 ASSERT_TRUE(packet16.has_timestamp());
1275 EXPECT_EQ(packet16.timestamp(), 36u);
1276 ASSERT_TRUE(packet16.has_frame_timeline_event());
1277
1278 const auto& event16 = packet16.frame_timeline_event();
1279 const auto& actualSkippedDisplayFrameStart = event16.actual_display_frame_start();
1280 validateTraceEvent(actualSkippedDisplayFrameStart, protoSkippedActualDisplayFrameStart);
1281
1282 // Packet - 17: Actual skipped Display Frame End
1283 // the timestamp should be equal to the 2nd expected surface frame's present time
1284 const auto& packet17 = packets[17];
1285 ASSERT_TRUE(packet17.has_timestamp());
1286 EXPECT_EQ(packet17.timestamp(), 70u);
1287 ASSERT_TRUE(packet17.has_frame_timeline_event());
1288
1289 const auto& event17 = packet17.frame_timeline_event();
1290 const auto& actualSkippedDisplayFrameEnd = event17.frame_end();
1291 validateTraceEvent(actualSkippedDisplayFrameEnd, protoSkippedActualDisplayFrameEnd);
1292}
1293
Adithya Srinivasan01189672020-10-20 14:23:05 -07001294TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
1295 auto tracingSession = getTracingSessionForTest();
1296 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001297
1298 tracingSession->StartBlocking();
Ady Abraham57a8ab42023-01-26 15:28:19 -08001299
1300 // Add an empty surface frame so that display frame would get traced.
1301 addEmptySurfaceFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001302 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001303
1304 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001305 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001306 mFrameTimeline->setSfPresent(26, presentFence1);
1307 presentFence1->signalForTest(31);
1308
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001309 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001310 auto protoExpectedDisplayFrameStart =
1311 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1312 kSurfaceFlingerPid);
1313 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1314 auto protoActualDisplayFrameStart =
1315 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
1316 kSurfaceFlingerPid,
1317 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001318 FrameTimelineEvent::JANK_NONE,
Ying Wei96eb5352023-11-21 17:37:21 +00001319 FrameTimelineEvent::SEVERITY_NONE,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001320 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001321 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001322
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001323 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001324 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001325 tracingSession->StopBlocking();
1326
1327 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001328 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001329
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001330 // Packet - 0 : ExpectedDisplayFrameStart
1331 const auto& packet0 = packets[0];
1332 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001333 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001334 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001335
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001336 const auto& event0 = packet0.frame_timeline_event();
1337 ASSERT_TRUE(event0.has_expected_display_frame_start());
1338 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
1339 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
1340
1341 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
1342 const auto& packet1 = packets[1];
1343 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001344 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001345 ASSERT_TRUE(packet1.has_frame_timeline_event());
1346
1347 const auto& event1 = packet1.frame_timeline_event();
1348 ASSERT_TRUE(event1.has_frame_end());
1349 const auto& expectedDisplayFrameEnd = event1.frame_end();
1350 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
1351
1352 // Packet - 2 : ActualDisplayFrameStart
1353 const auto& packet2 = packets[2];
1354 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001355 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001356 ASSERT_TRUE(packet2.has_frame_timeline_event());
1357
1358 const auto& event2 = packet2.frame_timeline_event();
1359 ASSERT_TRUE(event2.has_actual_display_frame_start());
1360 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1361 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1362
1363 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1364 const auto& packet3 = packets[3];
1365 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001366 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001367 ASSERT_TRUE(packet3.has_frame_timeline_event());
1368
1369 const auto& event3 = packet3.frame_timeline_event();
1370 ASSERT_TRUE(event3.has_frame_end());
1371 const auto& actualDisplayFrameEnd = event3.frame_end();
1372 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001373}
1374
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001375TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1376 auto tracingSession = getTracingSessionForTest();
1377 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1378
1379 tracingSession->StartBlocking();
1380 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1381 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001382 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001383
Ady Abraham57a8ab42023-01-26 15:28:19 -08001384 // Add an empty surface frame so that display frame would get traced.
1385 addEmptySurfaceFrame();
1386
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001387 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001388 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001389 mFrameTimeline->setSfPresent(26, presentFence1);
1390 presentFence1->signalForTest(31);
1391
1392 int64_t traceCookie = snoopCurrentTraceCookie();
1393
1394 auto protoActualDisplayFrameStart =
1395 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1396 kSurfaceFlingerPid,
1397 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001398 false, FrameTimelineEvent::JANK_UNKNOWN,
Ying Wei96eb5352023-11-21 17:37:21 +00001399 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001400 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001401 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1402
1403 addEmptyDisplayFrame();
1404 flushTrace();
1405 tracingSession->StopBlocking();
1406
1407 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1408 // Only actual timeline packets should be in the trace
1409 EXPECT_EQ(packets.size(), 2u);
1410
1411 // Packet - 0 : ActualDisplayFrameStart
1412 const auto& packet0 = packets[0];
1413 ASSERT_TRUE(packet0.has_timestamp());
1414 EXPECT_EQ(packet0.timestamp(), 20u);
1415 ASSERT_TRUE(packet0.has_frame_timeline_event());
1416
1417 const auto& event0 = packet0.frame_timeline_event();
1418 ASSERT_TRUE(event0.has_actual_display_frame_start());
1419 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1420 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1421
1422 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1423 const auto& packet1 = packets[1];
1424 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001425 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001426 ASSERT_TRUE(packet1.has_frame_timeline_event());
1427
1428 const auto& event1 = packet1.frame_timeline_event();
1429 ASSERT_TRUE(event1.has_frame_end());
1430 const auto& actualDisplayFrameEnd = event1.frame_end();
1431 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1432}
1433
Adithya Srinivasan01189672020-10-20 14:23:05 -07001434TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1435 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001436 // Layer specific increment
Edgar Arriaga631e4252023-03-02 02:11:24 +00001437 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001438 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1439 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1440
1441 tracingSession->StartBlocking();
1442 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1443 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001444
Huihong Luo3bdef862022-03-03 11:57:19 -08001445 FrameTimelineInfo ftInfo;
1446 ftInfo.vsyncId = surfaceFrameToken;
1447 ftInfo.inputEventId = sInputEventId;
1448
Adithya Srinivasan01189672020-10-20 14:23:05 -07001449 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001450 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1451 sLayerNameOne, sLayerNameOne,
1452 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001453 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001454 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1455 sLayerNameOne, sLayerNameOne,
1456 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001457 surfaceFrame1->setActualQueueTime(10);
1458 surfaceFrame1->setDropTime(15);
1459
1460 surfaceFrame2->setActualQueueTime(15);
1461 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001462
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001463 // First 2 cookies will be used by the DisplayFrame
1464 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1465
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001466 auto protoDroppedSurfaceFrameExpectedStart =
1467 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1468 displayFrameToken1, sPidOne, sLayerNameOne);
1469 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1470 auto protoDroppedSurfaceFrameActualStart =
1471 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1472 displayFrameToken1, sPidOne, sLayerNameOne,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001473 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1474 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001475 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001476 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001477 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001478
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001479 auto protoPresentedSurfaceFrameExpectedStart =
1480 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1481 displayFrameToken1, sPidOne, sLayerNameOne);
1482 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1483 auto protoPresentedSurfaceFrameActualStart =
1484 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1485 displayFrameToken1, sPidOne, sLayerNameOne,
1486 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001487 FrameTimelineEvent::JANK_NONE,
Ying Wei96eb5352023-11-21 17:37:21 +00001488 FrameTimelineEvent::SEVERITY_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001489 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001490 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001491
1492 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001493 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001494 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1495 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001496 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001497 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001498 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001499 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001500
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001501 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001502 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001503 tracingSession->StopBlocking();
1504
1505 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001506 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1507 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001508
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001509 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001510 const auto& packet4 = packets[4];
1511 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001512 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001513 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001514
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001515 const auto& event4 = packet4.frame_timeline_event();
1516 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001517 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1518 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001519
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001520 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001521 const auto& packet5 = packets[5];
1522 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001523 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001524 ASSERT_TRUE(packet5.has_frame_timeline_event());
1525
1526 const auto& event5 = packet5.frame_timeline_event();
1527 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001528 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1529 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001530
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001531 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001532 const auto& packet6 = packets[6];
1533 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001534 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001535 ASSERT_TRUE(packet6.has_frame_timeline_event());
1536
1537 const auto& event6 = packet6.frame_timeline_event();
1538 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001539 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1540 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001541
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001542 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001543 const auto& packet7 = packets[7];
1544 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001545 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001546 ASSERT_TRUE(packet7.has_frame_timeline_event());
1547
1548 const auto& event7 = packet7.frame_timeline_event();
1549 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001550 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1551 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1552
1553 // Packet - 8 : ExpectedSurfaceFrameStart2
1554 const auto& packet8 = packets[8];
1555 ASSERT_TRUE(packet8.has_timestamp());
1556 EXPECT_EQ(packet8.timestamp(), 10u);
1557 ASSERT_TRUE(packet8.has_frame_timeline_event());
1558
1559 const auto& event8 = packet8.frame_timeline_event();
1560 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1561 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1562 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1563
1564 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1565 const auto& packet9 = packets[9];
1566 ASSERT_TRUE(packet9.has_timestamp());
1567 EXPECT_EQ(packet9.timestamp(), 25u);
1568 ASSERT_TRUE(packet9.has_frame_timeline_event());
1569
1570 const auto& event9 = packet9.frame_timeline_event();
1571 ASSERT_TRUE(event9.has_frame_end());
1572 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1573 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1574
1575 // Packet - 10 : ActualSurfaceFrameStart2
1576 const auto& packet10 = packets[10];
1577 ASSERT_TRUE(packet10.has_timestamp());
1578 EXPECT_EQ(packet10.timestamp(), 10u);
1579 ASSERT_TRUE(packet10.has_frame_timeline_event());
1580
1581 const auto& event10 = packet10.frame_timeline_event();
1582 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1583 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1584 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1585
1586 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1587 const auto& packet11 = packets[11];
1588 ASSERT_TRUE(packet11.has_timestamp());
1589 EXPECT_EQ(packet11.timestamp(), 20u);
1590 ASSERT_TRUE(packet11.has_frame_timeline_event());
1591
1592 const auto& event11 = packet11.frame_timeline_event();
1593 ASSERT_TRUE(event11.has_frame_end());
1594 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1595 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1596}
1597
Ady Abrahame43ff722022-02-15 14:44:25 -08001598TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredIsAppMissedDeadline) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001599 auto tracingSession = getTracingSessionForTest();
1600 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1601
1602 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001603 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1604 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1605 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001606 int64_t surfaceFrameToken =
1607 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1608
1609 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001610 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001611 FrameTimelineInfo ftInfo;
1612 ftInfo.vsyncId = surfaceFrameToken;
1613 ftInfo.inputEventId = 0;
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001614 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001615 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1616 sLayerNameOne, sLayerNameOne,
1617 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001618 surfaceFrame1->setActualQueueTime(appEndTime);
1619 surfaceFrame1->setAcquireFenceTime(appEndTime);
1620
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001621 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1622 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1623 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001624 int64_t displayFrameToken =
1625 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1626
1627 // First 2 cookies will be used by the DisplayFrame
1628 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1629
1630 auto protoActualSurfaceFrameStart =
1631 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1632 displayFrameToken, sPidOne, sLayerNameOne,
1633 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Ady Abrahame43ff722022-02-15 14:44:25 -08001634 false, FrameTimelineEvent::JANK_APP_DEADLINE_MISSED,
Ying Wei96eb5352023-11-21 17:37:21 +00001635 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001636 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001637 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1638
1639 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001640 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001641 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1642 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1643 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1644 presentFence1->signalForTest(sfPresentTime);
1645
1646 addEmptyDisplayFrame();
1647 flushTrace();
1648 tracingSession->StopBlocking();
1649
1650 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1651 // Display Frame 4 packets + SurfaceFrame 2 packets
1652 ASSERT_EQ(packets.size(), 6u);
1653
1654 // Packet - 4 : ActualSurfaceFrameStart
1655 const auto& packet4 = packets[4];
1656 ASSERT_TRUE(packet4.has_timestamp());
1657 EXPECT_EQ(packet4.timestamp(),
1658 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1659 ASSERT_TRUE(packet4.has_frame_timeline_event());
1660
1661 const auto& event4 = packet4.frame_timeline_event();
1662 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1663 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1664 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1665
1666 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1667 const auto& packet5 = packets[5];
1668 ASSERT_TRUE(packet5.has_timestamp());
1669 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1670 ASSERT_TRUE(packet5.has_frame_timeline_event());
1671
1672 const auto& event5 = packet5.frame_timeline_event();
1673 ASSERT_TRUE(event5.has_frame_end());
1674 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001675 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001676}
1677
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001678TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDroppedFramesTracedProperly) {
1679 auto tracingSession = getTracingSessionForTest();
1680 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1681
1682 tracingSession->StartBlocking();
1683 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1684 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1685 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
1686 int64_t surfaceFrameToken =
1687 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1688
1689 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001690 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001691 FrameTimelineInfo ftInfo;
1692 ftInfo.vsyncId = surfaceFrameToken;
1693 ftInfo.inputEventId = 0;
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001694 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001695 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1696 sLayerNameOne, sLayerNameOne,
1697 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001698
1699 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(22ms).count();
1700 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1701 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
1702 int64_t displayFrameToken =
1703 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1704
1705 // First 2 cookies will be used by the DisplayFrame
1706 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1707
1708 auto protoActualSurfaceFrameStart =
1709 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1710 displayFrameToken, sPidOne, sLayerNameOne,
1711 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001712 FrameTimelineEvent::JANK_DROPPED,
Ying Wei96eb5352023-11-21 17:37:21 +00001713 FrameTimelineEvent::SEVERITY_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001714 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001715 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1716
1717 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001718 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001719 surfaceFrame1->setDropTime(sfStartTime);
1720 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1721 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1722 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1723 presentFence1->signalForTest(sfPresentTime);
1724
1725 addEmptyDisplayFrame();
1726 flushTrace();
1727 tracingSession->StopBlocking();
1728
1729 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1730 // Display Frame 4 packets + SurfaceFrame 2 packets
1731 ASSERT_EQ(packets.size(), 6u);
1732
1733 // Packet - 4 : ActualSurfaceFrameStart
1734 const auto& packet4 = packets[4];
1735 ASSERT_TRUE(packet4.has_timestamp());
1736 EXPECT_EQ(packet4.timestamp(),
1737 static_cast<uint64_t>(sfStartTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1738 ASSERT_TRUE(packet4.has_frame_timeline_event());
1739
1740 const auto& event4 = packet4.frame_timeline_event();
1741 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1742 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1743 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1744
1745 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1746 const auto& packet5 = packets[5];
1747 ASSERT_TRUE(packet5.has_timestamp());
1748 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(sfStartTime));
1749 ASSERT_TRUE(packet5.has_frame_timeline_event());
1750
1751 const auto& event5 = packet5.frame_timeline_event();
1752 ASSERT_TRUE(event5.has_frame_end());
1753 const auto& actualSurfaceFrameEnd = event5.frame_end();
1754 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
1755}
1756
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001757// Tests for Jank classification
1758TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001759 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001760 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001761 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1762 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001763 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -08001764 FrameTimelineInfo ftInfo;
1765 ftInfo.vsyncId = surfaceFrameToken;
1766 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001767 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -08001768 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1769 sLayerNameOne, sLayerNameOne,
1770 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001771 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001772 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1773 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1774 mFrameTimeline->setSfPresent(26, presentFence1);
1775 auto displayFrame = getDisplayFrame(0);
1776 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1777 presentFence1->signalForTest(29);
1778
1779 // Fences haven't been flushed yet, so it should be 0
1780 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1781 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1782
1783 addEmptyDisplayFrame();
1784 displayFrame = getDisplayFrame(0);
1785
1786 // Fences have flushed, so the present timestamps should be updated
1787 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1788 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1789 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1790 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1791 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00001792 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001793}
1794
1795TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001796 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001797 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001798 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1799 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001800 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001801 mFrameTimeline->setSfPresent(26, presentFence1);
1802 auto displayFrame = getDisplayFrame(0);
1803 presentFence1->signalForTest(30);
1804
1805 // Fences for the first frame haven't been flushed yet, so it should be 0
1806 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1807
1808 // Trigger a flush by finalizing the next DisplayFrame
1809 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001810 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001811 mFrameTimeline->setSfPresent(56, presentFence2);
1812 displayFrame = getDisplayFrame(0);
1813
1814 // Fences for the first frame have flushed, so the present timestamps should be updated
1815 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1816 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1817 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1818 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00001819 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001820
1821 // Fences for the second frame haven't been flushed yet, so it should be 0
1822 auto displayFrame2 = getDisplayFrame(1);
1823 presentFence2->signalForTest(65);
1824 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001825 addEmptyDisplayFrame();
1826 displayFrame2 = getDisplayFrame(1);
1827
1828 // Fences for the second frame have flushed, so the present timestamps should be updated
1829 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1830 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1831 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1832 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00001833 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001834}
1835
1836TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001837 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001838 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001839 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1840 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001841 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001842 mFrameTimeline->setSfPresent(26, presentFence1);
1843 auto displayFrame = getDisplayFrame(0);
1844 presentFence1->signalForTest(50);
1845
1846 // Fences for the first frame haven't been flushed yet, so it should be 0
1847 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1848
1849 // Trigger a flush by finalizing the next DisplayFrame
1850 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001851 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001852 mFrameTimeline->setSfPresent(56, presentFence2);
1853 displayFrame = getDisplayFrame(0);
1854
1855 // Fences for the first frame have flushed, so the present timestamps should be updated
1856 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1857 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1858 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1859 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00001860 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001861
1862 // Fences for the second frame haven't been flushed yet, so it should be 0
1863 auto displayFrame2 = getDisplayFrame(1);
1864 presentFence2->signalForTest(75);
1865 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1866
1867 addEmptyDisplayFrame();
1868 displayFrame2 = getDisplayFrame(1);
1869
1870 // Fences for the second frame have flushed, so the present timestamps should be updated
1871 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1872 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1873 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1874 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00001875 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001876}
1877
1878TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001879 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1880 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001881 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001882
1883 mFrameTimeline->setSfPresent(22, presentFence1);
1884 auto displayFrame = getDisplayFrame(0);
1885 presentFence1->signalForTest(28);
1886
1887 // Fences haven't been flushed yet, so it should be 0
1888 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1889
1890 addEmptyDisplayFrame();
1891 displayFrame = getDisplayFrame(0);
1892
1893 // Fences have flushed, so the present timestamps should be updated
1894 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1895 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1896 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1897 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00001898 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001899}
1900
1901TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001902 /*
1903 * Case 1 - cpu time > vsync period but combined time > deadline > deadline -> cpudeadlinemissed
1904 * Case 2 - cpu time < vsync period but combined time > deadline -> gpudeadlinemissed
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001905 * Case 3 - previous frame ran longer -> sf_stuffing
1906 * Case 4 - Long cpu under SF stuffing -> cpudeadlinemissed
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001907 */
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001908 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001909 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001910 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1911 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001912 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1913 auto gpuFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001914 auto gpuFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1915 auto gpuFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001916 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001917 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001918 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1919 int64_t sfToken4 = mTokenManager->generateTokenForPredictions({112, 120, 120});
1920
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001921 // case 1 - cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001922 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001923 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
1924 auto displayFrame0 = getDisplayFrame(0);
1925 gpuFence1->signalForTest(36);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001926 presentFence1->signalForTest(52);
1927
1928 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001929 EXPECT_EQ(displayFrame0->getActuals().presentTime, 0);
1930
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001931 // case 2 - cpu time = 56 - 52 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001932 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001933 mFrameTimeline->setSfPresent(56, presentFence2, gpuFence2);
1934 auto displayFrame1 = getDisplayFrame(1);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001935 gpuFence2->signalForTest(76);
1936 presentFence2->signalForTest(90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001937
1938 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1939 // Fences have flushed for first displayFrame, so the present timestamps should be updated
1940 EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
1941 EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1942 EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Rachel Lee94917b32022-03-18 17:52:09 -07001943 EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00001944 EXPECT_EQ(displayFrame0->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001945
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001946 // case 3 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001947 mFrameTimeline->setSfWakeUp(sfToken3, 106, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001948 mFrameTimeline->setSfPresent(112, presentFence3, gpuFence3);
1949 auto displayFrame2 = getDisplayFrame(2);
1950 gpuFence3->signalForTest(116);
1951 presentFence3->signalForTest(120);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001952
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001953 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001954 // Fences have flushed for second displayFrame, so the present timestamps should be updated
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001955 EXPECT_EQ(displayFrame1->getActuals().presentTime, 90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001956 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1957 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1958 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00001959 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001960
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001961 // case 4 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001962 mFrameTimeline->setSfWakeUp(sfToken4, 120, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001963 mFrameTimeline->setSfPresent(140, presentFence4, gpuFence4);
1964 auto displayFrame3 = getDisplayFrame(3);
1965 gpuFence4->signalForTest(156);
1966 presentFence4->signalForTest(180);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001967
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001968 EXPECT_EQ(displayFrame3->getActuals().presentTime, 0);
1969 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1970 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1971 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1972 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1973 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00001974 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001975
1976 addEmptyDisplayFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001977
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001978 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1979 EXPECT_EQ(displayFrame3->getActuals().presentTime, 180);
1980 EXPECT_EQ(displayFrame3->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1981 EXPECT_EQ(displayFrame3->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1982 EXPECT_EQ(displayFrame3->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00001983 EXPECT_EQ(displayFrame3->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001984}
1985
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001986TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001987 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001988 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001989 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1990 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001991 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1992 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08001993 FrameTimelineInfo ftInfo;
1994 ftInfo.vsyncId = surfaceFrameToken1;
1995 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001996 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001997 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1998 sLayerNameOne, sLayerNameOne,
1999 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002000 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002001 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002002 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2003 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002004 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002005 auto displayFrame1 = getDisplayFrame(0);
2006 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2007 presentFence1->signalForTest(30);
2008
2009 // Fences for the first frame haven't been flushed yet, so it should be 0
2010 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2011 auto actuals1 = presentedSurfaceFrame1.getActuals();
2012 EXPECT_EQ(actuals1.presentTime, 0);
2013
2014 // Trigger a flush by finalizing the next DisplayFrame
2015 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002016 FrameTimelineInfo ftInfo2;
2017 ftInfo2.vsyncId = surfaceFrameToken2;
2018 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002019 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002020 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2021 sLayerNameOne, sLayerNameOne,
2022 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002023 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002024 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002025 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2026 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002027 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002028 auto displayFrame2 = getDisplayFrame(1);
2029 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2030
2031 // Fences for the first frame have flushed, so the present timestamps should be updated
2032 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
2033 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2034 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2035 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00002036 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002037
2038 actuals1 = presentedSurfaceFrame1.getActuals();
2039 EXPECT_EQ(actuals1.presentTime, 30);
2040 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2041 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2042 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
Ying Wei96eb5352023-11-21 17:37:21 +00002043 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002044
2045 // Fences for the second frame haven't been flushed yet, so it should be 0
2046 presentFence2->signalForTest(65);
2047 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2048 auto actuals2 = presentedSurfaceFrame2.getActuals();
2049 EXPECT_EQ(actuals2.presentTime, 0);
2050
Alec Mouri363faf02021-01-29 16:34:55 -08002051 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
2052
2053 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002054 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
2055 sLayerNameOne, sGameMode,
2056 JankType::PredictionError, -3, 5,
2057 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08002058
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002059 addEmptyDisplayFrame();
2060
2061 // Fences for the second frame have flushed, so the present timestamps should be updated
2062 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
2063 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2064 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2065 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002066 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002067
2068 actuals2 = presentedSurfaceFrame2.getActuals();
2069 EXPECT_EQ(actuals2.presentTime, 65);
2070 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2071 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2072 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002073 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002074}
2075
2076TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08002077 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002078 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002079 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
2080 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002081 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
2082 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08002083 FrameTimelineInfo ftInfo;
2084 ftInfo.vsyncId = surfaceFrameToken1;
2085 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002086 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002087 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2088 sLayerNameOne, sLayerNameOne,
2089 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002090 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002091 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002092 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2093 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2094 mFrameTimeline->setSfPresent(26, presentFence1);
2095 auto displayFrame1 = getDisplayFrame(0);
2096 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2097 presentFence1->signalForTest(50);
2098
2099 // Fences for the first frame haven't been flushed yet, so it should be 0
2100 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2101 auto actuals1 = presentedSurfaceFrame1.getActuals();
2102 EXPECT_EQ(actuals1.presentTime, 0);
2103
2104 // Trigger a flush by finalizing the next DisplayFrame
2105 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002106 FrameTimelineInfo ftInfo2;
2107 ftInfo2.vsyncId = surfaceFrameToken2;
2108 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002109 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002110 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2111 sLayerNameOne, sLayerNameOne,
2112 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002113 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002114 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002115 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2116 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002117 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002118 auto displayFrame2 = getDisplayFrame(1);
2119 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2120
2121 // Fences for the first frame have flushed, so the present timestamps should be updated
2122 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
2123 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2124 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2125 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002126 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002127
2128 actuals1 = presentedSurfaceFrame1.getActuals();
2129 EXPECT_EQ(actuals1.presentTime, 50);
2130 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2131 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2132 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002133 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002134
2135 // Fences for the second frame haven't been flushed yet, so it should be 0
2136 presentFence2->signalForTest(86);
2137 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2138 auto actuals2 = presentedSurfaceFrame2.getActuals();
2139 EXPECT_EQ(actuals2.presentTime, 0);
2140
Alec Mouri363faf02021-01-29 16:34:55 -08002141 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
2142
2143 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002144 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
2145 sLayerNameOne, sGameMode,
2146 JankType::PredictionError, -3, 5,
2147 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08002148
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002149 addEmptyDisplayFrame();
2150
2151 // Fences for the second frame have flushed, so the present timestamps should be updated
2152 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
2153 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2154 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2155 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002156 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002157
2158 actuals2 = presentedSurfaceFrame2.getActuals();
2159 EXPECT_EQ(actuals2.presentTime, 86);
2160 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2161 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2162 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
Ying Wei96eb5352023-11-21 17:37:21 +00002163 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002164}
2165
2166TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08002167 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08002168
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002169 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002170 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002171 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -08002172 FrameTimelineInfo ftInfo;
2173 ftInfo.vsyncId = surfaceFrameToken1;
2174 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002175 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002176 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2177 sLayerNameOne, sLayerNameOne,
2178 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002179 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002180 mFrameTimeline->setSfWakeUp(sfToken1, 42, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002181 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2182 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2183 mFrameTimeline->setSfPresent(46, presentFence1);
2184 auto displayFrame1 = getDisplayFrame(0);
2185 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2186 presentFence1->signalForTest(50);
2187
2188 // Fences for the first frame haven't been flushed yet, so it should be 0
2189 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2190 auto actuals1 = presentedSurfaceFrame1.getActuals();
2191 EXPECT_EQ(actuals1.presentTime, 0);
2192
2193 addEmptyDisplayFrame();
2194
2195 // Fences for the first frame have flushed, so the present timestamps should be updated
2196 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
2197 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2198 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2199 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002200 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002201
2202 actuals1 = presentedSurfaceFrame1.getActuals();
2203 EXPECT_EQ(actuals1.presentTime, 50);
2204 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
2205 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2206 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
Ying Wei96eb5352023-11-21 17:37:21 +00002207 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002208}
2209
2210TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002211 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as only
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002212 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002213 // jank to the SurfaceFrame along with AppDeadlineMissed.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002214
Alec Mouri363faf02021-01-29 16:34:55 -08002215 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002216 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002217 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
2218 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002219 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
2220 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
Huihong Luo3bdef862022-03-03 11:57:19 -08002221 FrameTimelineInfo ftInfo;
2222 ftInfo.vsyncId = surfaceFrameToken1;
2223 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002224 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002225 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2226 sLayerNameOne, sLayerNameOne,
2227 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002228 surfaceFrame1->setAcquireFenceTime(26);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002229 mFrameTimeline->setSfWakeUp(sfToken1, 32, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002230 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2231 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2232 mFrameTimeline->setSfPresent(36, presentFence1);
2233 auto displayFrame1 = getDisplayFrame(0);
2234 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2235 presentFence1->signalForTest(40);
2236
2237 // Fences for the first frame haven't been flushed yet, so it should be 0
2238 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2239 auto actuals1 = presentedSurfaceFrame1.getActuals();
2240 EXPECT_EQ(actuals1.presentTime, 0);
2241
2242 // Trigger a flush by finalizing the next DisplayFrame
2243 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002244 FrameTimelineInfo ftInfo2;
2245 ftInfo2.vsyncId = surfaceFrameToken2;
2246 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002247 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002248 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2249 sLayerNameOne, sLayerNameOne,
2250 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002251 surfaceFrame2->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002252 mFrameTimeline->setSfWakeUp(sfToken2, 43, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002253 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2254 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2255 mFrameTimeline->setSfPresent(56, presentFence2);
2256 auto displayFrame2 = getDisplayFrame(1);
2257 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2258
2259 // Fences for the first frame have flushed, so the present timestamps should be updated
2260 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
2261 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2262 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2263 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002264 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002265
2266 actuals1 = presentedSurfaceFrame1.getActuals();
2267 EXPECT_EQ(actuals1.presentTime, 40);
2268 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2269 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2270 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002271 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002272
2273 // Fences for the second frame haven't been flushed yet, so it should be 0
2274 presentFence2->signalForTest(60);
2275 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2276 auto actuals2 = presentedSurfaceFrame2.getActuals();
2277 EXPECT_EQ(actuals2.presentTime, 0);
2278
2279 addEmptyDisplayFrame();
2280
2281 // Fences for the second frame have flushed, so the present timestamps should be updated
2282 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
2283 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2284 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2285 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002286 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002287
2288 actuals2 = presentedSurfaceFrame2.getActuals();
2289 EXPECT_EQ(actuals2.presentTime, 60);
2290 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2291 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002292 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2293 JankType::SurfaceFlingerCpuDeadlineMissed | JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002294 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Partial);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002295}
2296
2297TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002298 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08002299 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002300 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2301 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2302 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2303
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002304 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2305 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Huihong Luo3bdef862022-03-03 11:57:19 -08002306 FrameTimelineInfo ftInfo;
2307 ftInfo.vsyncId = surfaceFrameToken1;
2308 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002309 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002310 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2311 sLayerNameOne, sLayerNameOne,
2312 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002313 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002314 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002315 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2316 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2317 mFrameTimeline->setSfPresent(56, presentFence1);
2318 auto displayFrame1 = getDisplayFrame(0);
2319 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2320 presentFence1->signalForTest(60);
2321
2322 // Fences for the first frame haven't been flushed yet, so it should be 0
2323 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2324 auto actuals1 = presentedSurfaceFrame1.getActuals();
2325 EXPECT_EQ(actuals1.presentTime, 0);
2326
2327 // Trigger a flush by finalizing the next DisplayFrame
2328 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002329 FrameTimelineInfo ftInfo2;
2330 ftInfo2.vsyncId = surfaceFrameToken2;
2331 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002332 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002333 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2334 sLayerNameOne, sLayerNameOne,
2335 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002336 surfaceFrame2->setAcquireFenceTime(84);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002337 mFrameTimeline->setSfWakeUp(sfToken2, 112, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002338 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2339 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2340 mFrameTimeline->setSfPresent(116, presentFence2);
2341 auto displayFrame2 = getDisplayFrame(1);
2342 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2343 presentFence2->signalForTest(120);
2344
2345 // Fences for the first frame have flushed, so the present timestamps should be updated
2346 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2347 actuals1 = presentedSurfaceFrame1.getActuals();
2348 EXPECT_EQ(actuals1.endTime, 50);
2349 EXPECT_EQ(actuals1.presentTime, 60);
2350
2351 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2352 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2353 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002354 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002355
2356 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2357 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2358 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002359 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002360
2361 // Fences for the second frame haven't been flushed yet, so it should be 0
2362 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2363 auto actuals2 = presentedSurfaceFrame2.getActuals();
2364 EXPECT_EQ(actuals2.presentTime, 0);
2365
2366 addEmptyDisplayFrame();
2367
2368 // Fences for the second frame have flushed, so the present timestamps should be updated
2369 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
2370 actuals2 = presentedSurfaceFrame2.getActuals();
2371 EXPECT_EQ(actuals2.presentTime, 120);
2372
2373 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2374 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2375 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002376 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002377
2378 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2379 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2380 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2381 JankType::AppDeadlineMissed | JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00002382 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002383}
Alec Mouriadebf5c2021-01-05 12:57:36 -08002384
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002385TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
2386 // Layer specific increment
2387 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
2388 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2389 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2390 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2391
2392 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2393 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -08002394 FrameTimelineInfo ftInfo;
2395 ftInfo.vsyncId = surfaceFrameToken1;
2396 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002397 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002398 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2399 sLayerNameOne, sLayerNameOne,
2400 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002401 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002402 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002403 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2404 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2405 mFrameTimeline->setSfPresent(56, presentFence1);
2406 auto displayFrame1 = getDisplayFrame(0);
2407 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2408 presentFence1->signalForTest(60);
2409
2410 // Fences for the first frame haven't been flushed yet, so it should be 0
2411 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2412 auto actuals1 = presentedSurfaceFrame1.getActuals();
2413 EXPECT_EQ(actuals1.presentTime, 0);
2414
2415 // Trigger a flush by finalizing the next DisplayFrame
2416 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002417 FrameTimelineInfo ftInfo2;
2418 ftInfo2.vsyncId = surfaceFrameToken2;
2419 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002420 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002421 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2422 sLayerNameOne, sLayerNameOne,
2423 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002424 surfaceFrame2->setAcquireFenceTime(80);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002425 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002426 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
2427 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2428 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2429 mFrameTimeline->setSfPresent(86, presentFence2);
2430 auto displayFrame2 = getDisplayFrame(1);
2431 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2432 presentFence2->signalForTest(90);
2433
2434 // Fences for the first frame have flushed, so the present timestamps should be updated
2435 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2436 actuals1 = presentedSurfaceFrame1.getActuals();
2437 EXPECT_EQ(actuals1.endTime, 50);
2438 EXPECT_EQ(actuals1.presentTime, 60);
2439
2440 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2441 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2442 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002443 EXPECT_EQ(displayFrame1->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002444
2445 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2446 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2447 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002448 EXPECT_EQ(presentedSurfaceFrame1.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002449
2450 // Fences for the second frame haven't been flushed yet, so it should be 0
2451 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2452 auto actuals2 = presentedSurfaceFrame2.getActuals();
2453 EXPECT_EQ(actuals2.presentTime, 0);
2454
2455 addEmptyDisplayFrame();
2456
2457 // Fences for the second frame have flushed, so the present timestamps should be updated
2458 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2459 actuals2 = presentedSurfaceFrame2.getActuals();
2460 EXPECT_EQ(actuals2.presentTime, 90);
2461
2462 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2463 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2464 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002465 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::None);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002466
2467 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2468 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2469 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
Ying Wei96eb5352023-11-21 17:37:21 +00002470 EXPECT_EQ(presentedSurfaceFrame2.getJankSeverityType(), JankSeverityType::Full);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002471}
2472
Rachel Lee94917b32022-03-18 17:52:09 -07002473TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent_GpuAndCpuMiss) {
2474 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2475 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2476 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2477 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2478 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2479
2480 // Case 1: cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002481 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Rachel Lee94917b32022-03-18 17:52:09 -07002482 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
2483 auto displayFrame = getDisplayFrame(0);
2484 gpuFence1->signalForTest(36);
2485 presentFence1->signalForTest(52);
2486
2487 // Fences haven't been flushed yet, so it should be 0
2488 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
2489
2490 addEmptyDisplayFrame();
2491 displayFrame = getDisplayFrame(0);
2492
2493 // Fences have flushed, so the present timestamps should be updated
2494 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
2495 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2496 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2497 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002498 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Full);
Rachel Lee94917b32022-03-18 17:52:09 -07002499
2500 // Case 2: No GPU fence so it will not use GPU composition.
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002501 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Rachel Lee94917b32022-03-18 17:52:09 -07002502 mFrameTimeline->setSfPresent(66, presentFence2);
2503 auto displayFrame2 = getDisplayFrame(2); // 2 because of previous empty frame
2504 presentFence2->signalForTest(90);
2505
2506 // Fences for the frame haven't been flushed yet, so it should be 0
2507 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2508
2509 addEmptyDisplayFrame();
2510
2511 // Fences have flushed, so the present timestamps should be updated
2512 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2513 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2514 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2515 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Ying Wei96eb5352023-11-21 17:37:21 +00002516 EXPECT_EQ(displayFrame2->getJankSeverityType(), JankSeverityType::Full);
Rachel Lee94917b32022-03-18 17:52:09 -07002517}
2518
Ady Abrahamfcb16862022-10-10 14:35:21 -07002519TEST_F(FrameTimelineTest, jankClassification_presentFenceError) {
2520 auto erroneousPresentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2521 auto erroneousPresentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2522 auto validPresentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2523 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2524 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2525 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({72, 80, 80});
2526
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002527 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002528 mFrameTimeline->setSfPresent(26, erroneousPresentFence1);
2529
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002530 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002531 mFrameTimeline->setSfPresent(60, erroneousPresentFence2);
2532
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002533 mFrameTimeline->setSfWakeUp(sfToken3, 72, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002534 mFrameTimeline->setSfPresent(80, validPresentFence);
2535
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002536 erroneousPresentFence2->signalForTest(2);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002537 validPresentFence->signalForTest(80);
2538
2539 addEmptyDisplayFrame();
2540
2541 {
2542 auto displayFrame = getDisplayFrame(0);
2543 EXPECT_EQ(displayFrame->getActuals().presentTime, 26);
2544 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2545 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002546 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002547 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002548 }
2549 {
2550 auto displayFrame = getDisplayFrame(1);
2551 EXPECT_EQ(displayFrame->getActuals().presentTime, 60);
2552 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2553 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002554 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ying Wei96eb5352023-11-21 17:37:21 +00002555 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::Unknown);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002556 }
2557 {
2558 auto displayFrame = getDisplayFrame(2);
2559 EXPECT_EQ(displayFrame->getActuals().presentTime, 80);
2560 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2561 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2562 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
Ying Wei96eb5352023-11-21 17:37:21 +00002563 EXPECT_EQ(displayFrame->getJankSeverityType(), JankSeverityType::None);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002564 }
2565}
2566
Alec Mouriadebf5c2021-01-05 12:57:36 -08002567TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
2568 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
2569}
2570
2571TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002572 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002573
2574 auto surfaceFrame1 =
2575 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002576 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002577 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002578 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2579 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2580 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2581 presentFence1->signalForTest(oneHundredMs);
2582 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2583
2584 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2585}
2586
2587TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002588 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2589 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002590 auto surfaceFrame1 =
2591 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002592 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002593 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002594 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2595 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2596 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2597 presentFence1->signalForTest(oneHundredMs);
2598 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2599
2600 auto surfaceFrame2 =
2601 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002602 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002603 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002604 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2605 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2606 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2607 presentFence2->signalForTest(twoHundredMs);
2608 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2609
2610 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
2611}
2612
2613TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002614 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2615 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002616 auto surfaceFrame1 =
2617 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002618 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002619 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002620 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2621 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2622 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2623 presentFence1->signalForTest(oneHundredMs);
2624 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2625
2626 auto surfaceFrame2 =
2627 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002628 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002629 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002630 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2631 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2632 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2633 presentFence2->signalForTest(twoHundredMs);
2634 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2635
2636 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
2637}
2638
2639TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002640 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2641 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002642 auto surfaceFrame1 =
2643 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002644 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002645 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002646 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2647 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2648 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2649 presentFence1->signalForTest(oneHundredMs);
2650 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2651
2652 auto surfaceFrame2 =
2653 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002654 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002655 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002656 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2657 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2658 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2659 presentFence2->signalForTest(twoHundredMs);
2660 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2661
2662 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2663}
2664
2665TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002666 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2667 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2668 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2669 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2670 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002671 auto surfaceFrame1 =
2672 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002673 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002674 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002675 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2676 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2677 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2678 presentFence1->signalForTest(oneHundredMs);
2679 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2680
2681 auto surfaceFrame2 =
2682 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002683 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002684 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002685 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2686 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2687 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2688 presentFence2->signalForTest(twoHundredMs);
2689 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2690
2691 auto surfaceFrame3 =
2692 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002693 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002694 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002695 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2696 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2697 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2698 presentFence3->signalForTest(threeHundredMs);
2699 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2700
2701 auto surfaceFrame4 =
2702 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002703 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002704 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002705 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2706 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2707 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2708 presentFence4->signalForTest(fiveHundredMs);
2709 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2710
2711 auto surfaceFrame5 =
2712 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002713 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002714 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002715 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2716 // Dropped frames will be excluded from fps computation
2717 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2718 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2719 presentFence5->signalForTest(sixHundredMs);
2720 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2721
2722 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2723}
2724
ramindaniea2bb822022-06-27 19:52:10 +00002725TEST_F(FrameTimelineTest, getMinTime) {
2726 // Use SurfaceFrame::getBaseTime to test the getMinTime.
2727 FrameTimelineInfo ftInfo;
2728
2729 // Valid prediction state test.
2730 ftInfo.vsyncId = 0L;
2731 mTokenManager->generateTokenForPredictions({10});
2732 auto surfaceFrame =
2733 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2734 sLayerNameOne, sLayerNameOne,
2735 /*isBuffer*/ true, sGameMode);
2736 ASSERT_EQ(surfaceFrame->getBaseTime(), 10);
2737
2738 // Test prediction state which is not valid.
2739 ftInfo.vsyncId = FrameTimelineInfo::INVALID_VSYNC_ID;
2740 surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2741 sLayerNameOne, sLayerNameOne,
2742 /*isBuffer*/ true, sGameMode);
2743 // Start time test.
2744 surfaceFrame->setActualStartTime(200);
2745 ASSERT_EQ(surfaceFrame->getBaseTime(), 200);
2746
2747 // End time test.
2748 surfaceFrame->setAcquireFenceTime(100);
2749 ASSERT_EQ(surfaceFrame->getBaseTime(), 100);
2750
2751 // Present time test.
2752 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2753 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2754 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2755 presentFence->signalForTest(std::chrono::nanoseconds(50ns).count());
2756 mFrameTimeline->setSfPresent(50, presentFence);
2757 ASSERT_EQ(surfaceFrame->getBaseTime(), 50);
2758}
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002759
2760TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingDisplayRate) {
2761 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2762 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2763 FrameTimelineInfo ftInfo;
2764 ftInfo.vsyncId = token1;
2765 ftInfo.inputEventId = sInputEventId;
2766 auto surfaceFrame =
2767 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2768 sLayerNameOne, sLayerNameOne,
2769 /*isBuffer*/ true, sGameMode);
2770
2771 mFrameTimeline->setSfWakeUp(token1, 20, RR_30, RR_11);
2772 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2773 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2774 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2775 mFrameTimeline->setSfPresent(50, presentFence1);
2776
2777 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 11);
2778}
2779
2780TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingAppFrameRate) {
2781 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2782 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2783 FrameTimelineInfo ftInfo;
2784 ftInfo.vsyncId = token1;
2785 ftInfo.inputEventId = sInputEventId;
2786 auto surfaceFrame =
2787 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2788 sLayerNameOne, sLayerNameOne,
2789 /*isBuffer*/ true, sGameMode);
2790 surfaceFrame->setRenderRate(RR_30);
2791 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
2792 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2793 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2794 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2795 mFrameTimeline->setSfPresent(50, presentFence1);
2796
2797 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 30);
2798}
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002799} // namespace android::frametimeline