blob: 636d852651720bc08a2c863b6abe824358e0df58 [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
Marin Shalamanovbed7fd32020-12-21 20:02:20 +010017
Alec Mouri9a29e672020-09-14 12:39:14 -070018#include "gmock/gmock-spec-builders.h"
19#include "mock/MockTimeStats.h"
Adithya Srinivasanf279e042020-08-17 14:56:27 -070020#undef LOG_TAG
21#define LOG_TAG "LibSurfaceFlingerUnittests"
22
23#include <FrameTimeline/FrameTimeline.h>
24#include <gtest/gtest.h>
25#include <log/log.h>
Adithya Srinivasan01189672020-10-20 14:23:05 -070026#include <perfetto/trace/trace.pb.h>
Adithya Srinivasanf279e042020-08-17 14:56:27 -070027#include <cinttypes>
28
29using namespace std::chrono_literals;
Alec Mouri363faf02021-01-29 16:34:55 -080030using testing::_;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -080031using testing::AtLeast;
Alec Mouri9a29e672020-09-14 12:39:14 -070032using testing::Contains;
Adithya Srinivasan01189672020-10-20 14:23:05 -070033using FrameTimelineEvent = perfetto::protos::FrameTimelineEvent;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000034using ProtoExpectedDisplayFrameStart =
35 perfetto::protos::FrameTimelineEvent_ExpectedDisplayFrameStart;
36using ProtoExpectedSurfaceFrameStart =
37 perfetto::protos::FrameTimelineEvent_ExpectedSurfaceFrameStart;
38using ProtoActualDisplayFrameStart = perfetto::protos::FrameTimelineEvent_ActualDisplayFrameStart;
39using ProtoActualSurfaceFrameStart = perfetto::protos::FrameTimelineEvent_ActualSurfaceFrameStart;
40using ProtoFrameEnd = perfetto::protos::FrameTimelineEvent_FrameEnd;
Adithya Srinivasan01189672020-10-20 14:23:05 -070041using ProtoPresentType = perfetto::protos::FrameTimelineEvent_PresentType;
42using ProtoJankType = perfetto::protos::FrameTimelineEvent_JankType;
Adithya Srinivasan78e58af2021-02-25 00:08:08 +000043using ProtoPredictionType = perfetto::protos::FrameTimelineEvent_PredictionType;
Alec Mouri9a29e672020-09-14 12:39:14 -070044
Adithya Srinivasanf279e042020-08-17 14:56:27 -070045namespace android::frametimeline {
46
Ady Abraham57a8ab42023-01-26 15:28:19 -080047static const std::string sLayerNameOne = "layer1";
48static const std::string sLayerNameTwo = "layer2";
49
50constexpr const uid_t sUidOne = 0;
51constexpr pid_t sPidOne = 10;
52constexpr pid_t sPidTwo = 20;
53constexpr int32_t sInputEventId = 5;
54constexpr int32_t sLayerIdOne = 1;
55constexpr int32_t sLayerIdTwo = 2;
56constexpr GameMode sGameMode = GameMode::Unsupported;
Pascal Muetschardac7bcd92023-10-03 15:05:36 +020057constexpr Fps RR_11 = Fps::fromPeriodNsecs(11);
58constexpr Fps RR_30 = Fps::fromPeriodNsecs(30);
Ady Abraham57a8ab42023-01-26 15:28:19 -080059
Adithya Srinivasanf279e042020-08-17 14:56:27 -070060class FrameTimelineTest : public testing::Test {
61public:
62 FrameTimelineTest() {
63 const ::testing::TestInfo* const test_info =
64 ::testing::UnitTest::GetInstance()->current_test_info();
65 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
66 }
67
68 ~FrameTimelineTest() {
69 const ::testing::TestInfo* const test_info =
70 ::testing::UnitTest::GetInstance()->current_test_info();
71 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
72 }
73
Adithya Srinivasan01189672020-10-20 14:23:05 -070074 static void SetUpTestSuite() {
75 // Need to initialize tracing in process for testing, and only once per test suite.
76 perfetto::TracingInitArgs args;
77 args.backends = perfetto::kInProcessBackend;
78 perfetto::Tracing::Initialize(args);
79 }
80
Adithya Srinivasanf279e042020-08-17 14:56:27 -070081 void SetUp() override {
Ady Abraham57f8e182022-03-08 15:54:33 -080082 constexpr bool kUseBootTimeClock = true;
Alec Mouri9a29e672020-09-14 12:39:14 -070083 mTimeStats = std::make_shared<mock::TimeStats>();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000084 mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats, kSurfaceFlingerPid,
Ady Abraham57f8e182022-03-08 15:54:33 -080085 kTestThresholds, !kUseBootTimeClock);
Adithya Srinivasan01189672020-10-20 14:23:05 -070086 mFrameTimeline->registerDataSource();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070087 mTokenManager = &mFrameTimeline->mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000088 mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
Adithya Srinivasan2d736322020-10-01 16:53:48 -070089 maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +000090 maxTokens = mTokenManager->kMaxTokens;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070091 }
92
Adithya Srinivasan01189672020-10-20 14:23:05 -070093 // Each tracing session can be used for a single block of Start -> Stop.
94 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
95 perfetto::TraceConfig cfg;
96 cfg.set_duration_ms(500);
97 cfg.add_buffers()->set_size_kb(1024);
98 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
99 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
100
101 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
102 tracingSession->Setup(cfg);
103 return tracingSession;
104 }
105
106 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
107 perfetto::TracingSession* tracingSession) {
108 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
109 perfetto::protos::Trace trace;
110 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
111
112 std::vector<perfetto::protos::TracePacket> packets;
113 for (const auto& packet : trace.packet()) {
114 if (!packet.has_frame_timeline_event()) {
115 continue;
116 }
117 packets.emplace_back(packet);
118 }
119 return packets;
120 }
121
Ady Abraham57a8ab42023-01-26 15:28:19 -0800122 void addEmptySurfaceFrame() {
123 auto surfaceFrame =
124 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
125 sLayerNameOne, sLayerNameOne,
126 /*isBuffer*/ false, sGameMode);
127 mFrameTimeline->addSurfaceFrame(std::move(surfaceFrame));
128 }
129
Adithya Srinivasan01189672020-10-20 14:23:05 -0700130 void addEmptyDisplayFrame() {
131 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000132 // Trigger a flushPresentFence by calling setSfPresent for the next frame
Adithya Srinivasan01189672020-10-20 14:23:05 -0700133 mFrameTimeline->setSfPresent(2500, presentFence1);
134 }
135
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000136 void flushTokens() {
137 for (size_t i = 0; i < maxTokens; i++) {
138 mTokenManager->generateTokenForPredictions({});
139 }
140 EXPECT_EQ(getPredictions().size(), maxTokens);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700141 }
142
143 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
144 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800145 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
146 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700147 }
148
149 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
150 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
151 return mFrameTimeline->mDisplayFrames[idx];
152 }
153
154 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
155 return a.startTime == b.startTime && a.endTime == b.endTime &&
156 a.presentTime == b.presentTime;
157 }
158
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000159 const std::map<int64_t, TimelineItem>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700160 return mTokenManager->mPredictions;
161 }
162
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000163 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700164 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
165 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
166 }
167
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000168 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
169
170 void flushTrace() {
171 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
172 FrameTimelineDataSource::Trace(
173 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
174 }
175
Alec Mouri9a29e672020-09-14 12:39:14 -0700176 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700177 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
178 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000179 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700180 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700181 uint32_t* maxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000182 size_t maxTokens;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000183 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasanead17162021-02-18 02:17:37 +0000184 static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan54996e22021-06-25 22:26:45 +0000185 static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(0ns).count();
Adithya Srinivasanead17162021-02-18 02:17:37 +0000186 static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800187 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
188 kDeadlineThreshold,
189 kStartThreshold};
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700190};
191
192TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
193 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000194 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000195 flushTokens();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700196 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
197 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
198
199 // token1 should have expired
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700200 EXPECT_EQ(predictions.has_value(), false);
201
202 predictions = mTokenManager->getPredictionsForToken(token2);
203 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
204}
205
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700206TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800207 auto surfaceFrame1 =
208 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000209 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000210 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -0800211 auto surfaceFrame2 =
212 mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000213 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000214 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700215 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
216 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
217}
218
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700219TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800220 auto surfaceFrame =
221 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000222 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000223 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700224 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
225}
226
227TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
228 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000229 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -0800230 FrameTimelineInfo ftInfo;
231 ftInfo.vsyncId = token1;
232 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000233 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800234 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
235 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000236 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700237
238 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
239}
240
241TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
242 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800243 FrameTimelineInfo ftInfo;
244 ftInfo.vsyncId = token1;
245 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000246 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800247 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
248 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000249 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700250
251 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
252 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
253}
254
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000255TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
256 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
257 constexpr int32_t inputEventId = 1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800258 FrameTimelineInfo ftInfo;
259 ftInfo.vsyncId = token1;
260 ftInfo.inputEventId = inputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000261 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800262 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
263 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000264 /*isBuffer*/ true, sGameMode);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000265
266 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
267}
268
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700269TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
270 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700271 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800272 FrameTimelineInfo ftInfo;
273 ftInfo.vsyncId = token1;
274 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000275 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800276 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
277 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000278 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700279
280 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200281 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000282 surfaceFrame1->setDropTime(12);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800283 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
284 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700285 mFrameTimeline->setSfPresent(25, presentFence1);
286 presentFence1->signalForTest(30);
287
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000288 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700289
290 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
291 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000292 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
293 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700294 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
295}
296
297TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800298 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800299 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700300 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
301 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700302 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800303 FrameTimelineInfo ftInfo;
304 ftInfo.vsyncId = surfaceFrameToken1;
305 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700306 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800307 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
308 sLayerNameOne, sLayerNameOne,
309 /*isBuffer*/ true, sGameMode);
Alec Mouri9a29e672020-09-14 12:39:14 -0700310 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800311 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdTwo,
312 sLayerNameTwo, sLayerNameTwo,
313 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200314 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800315 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
316 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
317 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
318 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700319 mFrameTimeline->setSfPresent(26, presentFence1);
320 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800321 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
322 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700323 presentFence1->signalForTest(42);
324
325 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800326 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700327 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
328 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
329
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000330 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700331
332 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800333 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700334 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
335 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100336 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
337 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700338}
339
340TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
341 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
342 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800343 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800344 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800345 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700346 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700347 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
348 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
349 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
350 int64_t sfToken = mTokenManager->generateTokenForPredictions(
351 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800352 FrameTimelineInfo ftInfo;
353 ftInfo.vsyncId = surfaceFrameToken;
354 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700355 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800356 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000357 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000358 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200359 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800360 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
361 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700362 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
363 presentFence->signalForTest(32 + frameTimeFactor);
364 frameTimeFactor += 30;
365 }
366 auto displayFrame0 = getDisplayFrame(0);
367
368 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800369 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700370
371 // Add one more display frame
372 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
373 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
374 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
375 int64_t sfToken = mTokenManager->generateTokenForPredictions(
376 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800377 FrameTimelineInfo ftInfo;
378 ftInfo.vsyncId = surfaceFrameToken;
379 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700380 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800381 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
382 sLayerNameOne, sLayerNameOne,
383 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200384 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800385 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
386 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700387 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
388 presentFence->signalForTest(32 + frameTimeFactor);
389 displayFrame0 = getDisplayFrame(0);
390
391 // The window should have slided by 1 now and the previous 0th display frame
392 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800393 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700394}
395
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700396TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000397 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
398 "acquireFenceAfterQueue",
399 "acquireFenceAfterQueue",
400 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700401 surfaceFrame->setActualQueueTime(123);
402 surfaceFrame->setAcquireFenceTime(456);
403 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
404}
405
406TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000407 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
408 "acquireFenceAfterQueue",
409 "acquireFenceAfterQueue",
410 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700411 surfaceFrame->setActualQueueTime(456);
412 surfaceFrame->setAcquireFenceTime(123);
413 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
414}
415
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700416TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
417 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
418 presentFence->signalForTest(2);
419
420 // Size shouldn't exceed maxDisplayFrames - 64
421 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700422 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800423 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000424 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000425 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700426 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200427 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800428 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
429 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700430 mFrameTimeline->setSfPresent(27, presentFence);
431 }
432 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
433
434 // Increase the size to 256
435 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000436 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700437
438 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700439 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800440 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000441 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000442 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700443 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200444 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800445 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
446 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700447 mFrameTimeline->setSfPresent(27, presentFence);
448 }
449 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
450
451 // Shrink the size to 128
452 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000453 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700454
455 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700456 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800457 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000458 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000459 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700460 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200461 mFrameTimeline->setSfWakeUp(sfToken, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800462 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
463 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700464 mFrameTimeline->setSfPresent(27, presentFence);
465 }
466 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
467}
Alec Mouri9a29e672020-09-14 12:39:14 -0700468
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000469TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200470 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000471
472 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
473 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
474 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800475 FrameTimelineInfo ftInfo;
476 ftInfo.vsyncId = surfaceFrameToken1;
477 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000478
479 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800480 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
481 sLayerNameOne, sLayerNameOne,
482 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200483 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000484 surfaceFrame1->setAcquireFenceTime(20);
485 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
486 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
487
488 mFrameTimeline->setSfPresent(59, presentFence1);
489 presentFence1->signalForTest(-1);
490 addEmptyDisplayFrame();
491
492 auto displayFrame0 = getDisplayFrame(0);
Ady Abrahamfcb16862022-10-10 14:35:21 -0700493 EXPECT_EQ(displayFrame0->getActuals().presentTime, 59);
Ady Abrahamb1e10d12023-03-13 15:23:54 -0700494 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000495 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
496 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
497}
498
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800499// Tests related to TimeStats
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000500TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200501 Fps refreshRate = RR_11;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000502 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
503 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
504 int64_t surfaceFrameToken1 = -1;
505 int64_t sfToken1 = -1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800506 FrameTimelineInfo ftInfo;
507 ftInfo.vsyncId = surfaceFrameToken1;
508 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000509
510 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800511 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
512 sLayerNameOne, sLayerNameOne,
513 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200514 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000515 surfaceFrame1->setAcquireFenceTime(20);
516 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
517 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
518 presentFence1->signalForTest(70);
519
520 mFrameTimeline->setSfPresent(59, presentFence1);
521}
522
Alec Mouri9a29e672020-09-14 12:39:14 -0700523TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200524 Fps refreshRate = RR_11;
Alec Mouri9a29e672020-09-14 12:39:14 -0700525 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800526 incrementJankyFrames(
527 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000528 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000529 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800530 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700531 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000532 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
533 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800534 FrameTimelineInfo ftInfo;
535 ftInfo.vsyncId = surfaceFrameToken1;
536 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000537
Alec Mouri9a29e672020-09-14 12:39:14 -0700538 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800539 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
540 sLayerNameOne, sLayerNameOne,
541 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200542 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000543 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800544 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
545 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000546 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700547
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000548 mFrameTimeline->setSfPresent(62, presentFence1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700549}
550
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000551TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfGpu) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200552 Fps refreshRate = RR_11;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000553 EXPECT_CALL(*mTimeStats,
554 incrementJankyFrames(
555 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000556 sLayerNameOne, sGameMode,
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000557 JankType::SurfaceFlingerGpuDeadlineMissed, 4, 10,
558 0}));
559 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
560 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
561 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
562 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800563 FrameTimelineInfo ftInfo;
564 ftInfo.vsyncId = surfaceFrameToken1;
565 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000566
567 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800568 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
569 sLayerNameOne, sLayerNameOne,
570 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200571 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000572 surfaceFrame1->setAcquireFenceTime(20);
573 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
574 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
575 gpuFence1->signalForTest(64);
576 presentFence1->signalForTest(70);
577
578 mFrameTimeline->setSfPresent(59, presentFence1, gpuFence1);
579}
580
Alec Mouri9a29e672020-09-14 12:39:14 -0700581TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200582 Fps refreshRate = RR_30;
Alec Mouri9a29e672020-09-14 12:39:14 -0700583 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800584 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000585 sLayerNameOne, sGameMode,
586 JankType::DisplayHAL, -4, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800587
Alec Mouri9a29e672020-09-14 12:39:14 -0700588 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000589 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
590 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800591 FrameTimelineInfo ftInfo;
592 ftInfo.vsyncId = surfaceFrameToken1;
593 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000594
Alec Mouri9a29e672020-09-14 12:39:14 -0700595 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800596 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
597 sLayerNameOne, sLayerNameOne,
598 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200599 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800600 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000601 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800602 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000603 presentFence1->signalForTest(90);
604 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800605 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700606}
607
608TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700609 Fps refreshRate = 11_Hz;
Alec Mouri9a29e672020-09-14 12:39:14 -0700610 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000611 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000612 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000613 JankType::AppDeadlineMissed, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000614 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700615 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000616 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
617 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800618 FrameTimelineInfo ftInfo;
619 ftInfo.vsyncId = surfaceFrameToken1;
620 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000621
Alec Mouri9a29e672020-09-14 12:39:14 -0700622 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800623 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
624 sLayerNameOne, sLayerNameOne,
625 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000626 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200627 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700628
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800629 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
630 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000631 presentFence1->signalForTest(90);
632 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100633
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800634 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700635}
636
Adithya Srinivasanead17162021-02-18 02:17:37 +0000637TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000638 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000639 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000640 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000641 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000642 JankType::SurfaceFlingerScheduling,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000643 -4, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000644 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000645 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
646 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800647 FrameTimelineInfo ftInfo;
648 ftInfo.vsyncId = surfaceFrameToken1;
649 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000650
Adithya Srinivasanead17162021-02-18 02:17:37 +0000651 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800652 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
653 sLayerNameOne, sLayerNameOne,
654 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000655 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200656 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000657
658 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
659 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000660 presentFence1->signalForTest(60);
661 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000662
663 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
664}
665
666TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000667 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000668 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000669 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000670 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000671 JankType::PredictionError, -4, 5,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000672 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000673 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000674 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
675 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800676 FrameTimelineInfo ftInfo;
677 ftInfo.vsyncId = surfaceFrameToken1;
678 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000679
Adithya Srinivasanead17162021-02-18 02:17:37 +0000680 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800681 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
682 sLayerNameOne, sLayerNameOne,
683 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000684 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200685 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000686
687 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
688 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000689 presentFence1->signalForTest(65);
690 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000691
692 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
693}
694
695TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000696 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000697 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000698 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000699 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000700 JankType::BufferStuffing, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000701 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000702 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000703 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
704 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800705 FrameTimelineInfo ftInfo;
706 ftInfo.vsyncId = surfaceFrameToken1;
707 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000708
Adithya Srinivasanead17162021-02-18 02:17:37 +0000709 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800710 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
711 sLayerNameOne, sLayerNameOne,
712 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000713 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200714 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000715
716 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000717 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000718 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000719 presentFence1->signalForTest(90);
720 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000721
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000722 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000723}
724
Alec Mouri363faf02021-01-29 16:34:55 -0800725TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200726 Fps refreshRate = RR_11;
727 Fps renderRate = RR_30;
Alec Mouri363faf02021-01-29 16:34:55 -0800728 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000729 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne,
730 sLayerNameOne, sGameMode,
731 JankType::AppDeadlineMissed, -4, 0,
732 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800733 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000734 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
735 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800736 FrameTimelineInfo ftInfo;
737 ftInfo.vsyncId = surfaceFrameToken1;
738 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000739
Alec Mouri363faf02021-01-29 16:34:55 -0800740 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800741 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
742 sLayerNameOne, sLayerNameOne,
743 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000744 surfaceFrame1->setAcquireFenceTime(45);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200745 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800746
747 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
748 surfaceFrame1->setRenderRate(renderRate);
749 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000750 presentFence1->signalForTest(90);
751 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800752
753 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
754}
755
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000756TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200757 Fps refreshRate = RR_11;
758 Fps renderRate = RR_30;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000759
760 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000761 incrementJankyFrames(
762 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000763 sGameMode,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000764 JankType::Unknown | JankType::AppDeadlineMissed,
Adithya Srinivasande272452021-04-10 00:21:00 +0000765 0, 0, 25}));
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000766 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
767 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
768 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800769 FrameTimelineInfo ftInfo;
770 ftInfo.vsyncId = surfaceFrameToken1;
771 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000772
773 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800774 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
775 sLayerNameOne, sLayerNameOne,
776 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000777 surfaceFrame1->setAcquireFenceTime(45);
778 // Trigger a prediction expiry
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000779 flushTokens();
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200780 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate, refreshRate);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000781
782 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
783 surfaceFrame1->setRenderRate(renderRate);
784 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
785 presentFence1->signalForTest(90);
786 mFrameTimeline->setSfPresent(86, presentFence1);
787
788 auto displayFrame = getDisplayFrame(0);
789 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
790 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
791 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
792 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
793
794 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000795 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000796}
797
Adithya Srinivasan01189672020-10-20 14:23:05 -0700798/*
799 * Tracing Tests
800 *
801 * Trace packets are flushed all the way only when the next packet is traced.
802 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
803 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
804 * will have additional empty frames created for this reason.
805 */
806TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
807 auto tracingSession = getTracingSessionForTest();
808 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700809 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800810 FrameTimelineInfo ftInfo;
811 ftInfo.vsyncId = token1;
812 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000813 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800814 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
815 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000816 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700817
818 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200819 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800820 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
821 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700822 mFrameTimeline->setSfPresent(25, presentFence1);
823 presentFence1->signalForTest(30);
824
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000825 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700826
827 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000828 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700829}
830
831TEST_F(FrameTimelineTest, tracing_sanityTest) {
832 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800833 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800834 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700835 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700836
837 tracingSession->StartBlocking();
838 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
839 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800840 FrameTimelineInfo ftInfo;
841 ftInfo.vsyncId = token1;
842 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000843 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800844 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
845 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000846 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700847
848 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200849 mFrameTimeline->setSfWakeUp(token2, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800850 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
851 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700852 mFrameTimeline->setSfPresent(25, presentFence1);
853 presentFence1->signalForTest(30);
854
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000855 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000856 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700857 tracingSession->StopBlocking();
858
859 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000860 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000861 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700862}
863
864TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
865 auto tracingSession = getTracingSessionForTest();
866 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700867
868 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700869
870 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200871 mFrameTimeline->setSfWakeUp(-1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700872 mFrameTimeline->setSfPresent(25, presentFence1);
873 presentFence1->signalForTest(30);
874
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000875 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000876 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700877 tracingSession->StopBlocking();
878
879 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000880 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700881}
882
883TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
884 auto tracingSession = getTracingSessionForTest();
885 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700886
887 tracingSession->StartBlocking();
888 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -0800889 auto surfaceFrame1 =
890 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000891 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000892 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700893
894 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +0200895 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800896 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
897 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700898 mFrameTimeline->setSfPresent(25, presentFence1);
899 presentFence1->signalForTest(30);
900
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000901 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000902 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700903 tracingSession->StopBlocking();
904
905 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000906 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
907 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000908 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700909}
910
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000911ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
912 pid_t pid) {
913 ProtoExpectedDisplayFrameStart proto;
914 proto.set_cookie(cookie);
915 proto.set_token(token);
916 proto.set_pid(pid);
917 return proto;
918}
919
920ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
921 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000922 bool gpuComposition, ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000923 ProtoActualDisplayFrameStart proto;
924 proto.set_cookie(cookie);
925 proto.set_token(token);
926 proto.set_pid(pid);
927 proto.set_present_type(presentType);
928 proto.set_on_time_finish(onTimeFinish);
929 proto.set_gpu_composition(gpuComposition);
930 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000931 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000932 return proto;
933}
934
935ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
936 int64_t displayFrameToken,
937 pid_t pid,
938 std::string layerName) {
939 ProtoExpectedSurfaceFrameStart proto;
940 proto.set_cookie(cookie);
941 proto.set_token(token);
942 proto.set_display_frame_token(displayFrameToken);
943 proto.set_pid(pid);
944 proto.set_layer_name(layerName);
945 return proto;
946}
947
948ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
949 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
950 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +0000951 ProtoJankType jankType, ProtoPredictionType predictionType, bool isBuffer) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000952 ProtoActualSurfaceFrameStart proto;
953 proto.set_cookie(cookie);
954 proto.set_token(token);
955 proto.set_display_frame_token(displayFrameToken);
956 proto.set_pid(pid);
957 proto.set_layer_name(layerName);
958 proto.set_present_type(presentType);
959 proto.set_on_time_finish(onTimeFinish);
960 proto.set_gpu_composition(gpuComposition);
961 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000962 proto.set_prediction_type(predictionType);
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +0000963 proto.set_is_buffer(isBuffer);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000964 return proto;
965}
966
967ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
968 ProtoFrameEnd proto;
969 proto.set_cookie(cookie);
970 return proto;
971}
972
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000973void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
974 const ProtoExpectedDisplayFrameStart& source) {
975 ASSERT_TRUE(received.has_cookie());
976 EXPECT_EQ(received.cookie(), source.cookie());
977
Adithya Srinivasan01189672020-10-20 14:23:05 -0700978 ASSERT_TRUE(received.has_token());
979 EXPECT_EQ(received.token(), source.token());
980
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000981 ASSERT_TRUE(received.has_pid());
982 EXPECT_EQ(received.pid(), source.pid());
983}
984
985void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
986 const ProtoActualDisplayFrameStart& source) {
987 ASSERT_TRUE(received.has_cookie());
988 EXPECT_EQ(received.cookie(), source.cookie());
989
990 ASSERT_TRUE(received.has_token());
991 EXPECT_EQ(received.token(), source.token());
992
993 ASSERT_TRUE(received.has_pid());
994 EXPECT_EQ(received.pid(), source.pid());
995
Adithya Srinivasan01189672020-10-20 14:23:05 -0700996 ASSERT_TRUE(received.has_present_type());
997 EXPECT_EQ(received.present_type(), source.present_type());
998 ASSERT_TRUE(received.has_on_time_finish());
999 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1000 ASSERT_TRUE(received.has_gpu_composition());
1001 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1002 ASSERT_TRUE(received.has_jank_type());
1003 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001004 ASSERT_TRUE(received.has_prediction_type());
1005 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001006}
1007
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001008void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
1009 const ProtoExpectedSurfaceFrameStart& source) {
1010 ASSERT_TRUE(received.has_cookie());
1011 EXPECT_EQ(received.cookie(), source.cookie());
1012
Adithya Srinivasan01189672020-10-20 14:23:05 -07001013 ASSERT_TRUE(received.has_token());
1014 EXPECT_EQ(received.token(), source.token());
1015
1016 ASSERT_TRUE(received.has_display_frame_token());
1017 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1018
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001019 ASSERT_TRUE(received.has_pid());
1020 EXPECT_EQ(received.pid(), source.pid());
1021
1022 ASSERT_TRUE(received.has_layer_name());
1023 EXPECT_EQ(received.layer_name(), source.layer_name());
1024}
1025
1026void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
1027 const ProtoActualSurfaceFrameStart& source) {
1028 ASSERT_TRUE(received.has_cookie());
1029 EXPECT_EQ(received.cookie(), source.cookie());
1030
1031 ASSERT_TRUE(received.has_token());
1032 EXPECT_EQ(received.token(), source.token());
1033
1034 ASSERT_TRUE(received.has_display_frame_token());
1035 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1036
1037 ASSERT_TRUE(received.has_pid());
1038 EXPECT_EQ(received.pid(), source.pid());
1039
1040 ASSERT_TRUE(received.has_layer_name());
1041 EXPECT_EQ(received.layer_name(), source.layer_name());
1042
Adithya Srinivasan01189672020-10-20 14:23:05 -07001043 ASSERT_TRUE(received.has_present_type());
1044 EXPECT_EQ(received.present_type(), source.present_type());
1045 ASSERT_TRUE(received.has_on_time_finish());
1046 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1047 ASSERT_TRUE(received.has_gpu_composition());
1048 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1049 ASSERT_TRUE(received.has_jank_type());
1050 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001051 ASSERT_TRUE(received.has_prediction_type());
1052 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001053 ASSERT_TRUE(received.has_is_buffer());
1054 EXPECT_EQ(received.is_buffer(), source.is_buffer());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001055}
Adithya Srinivasan01189672020-10-20 14:23:05 -07001056
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001057void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
1058 ASSERT_TRUE(received.has_cookie());
1059 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001060}
1061
1062TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
1063 auto tracingSession = getTracingSessionForTest();
1064 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001065
1066 tracingSession->StartBlocking();
Ady Abraham57a8ab42023-01-26 15:28:19 -08001067
1068 // Add an empty surface frame so that display frame would get traced.
1069 addEmptySurfaceFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001070 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001071
1072 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001073 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001074 mFrameTimeline->setSfPresent(26, presentFence1);
1075 presentFence1->signalForTest(31);
1076
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001077 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001078 auto protoExpectedDisplayFrameStart =
1079 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1080 kSurfaceFlingerPid);
1081 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1082 auto protoActualDisplayFrameStart =
1083 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
1084 kSurfaceFlingerPid,
1085 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001086 FrameTimelineEvent::JANK_NONE,
1087 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001088 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001089
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001090 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001091 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001092 tracingSession->StopBlocking();
1093
1094 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001095 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001096
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001097 // Packet - 0 : ExpectedDisplayFrameStart
1098 const auto& packet0 = packets[0];
1099 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001100 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001101 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001102
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001103 const auto& event0 = packet0.frame_timeline_event();
1104 ASSERT_TRUE(event0.has_expected_display_frame_start());
1105 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
1106 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
1107
1108 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
1109 const auto& packet1 = packets[1];
1110 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001111 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001112 ASSERT_TRUE(packet1.has_frame_timeline_event());
1113
1114 const auto& event1 = packet1.frame_timeline_event();
1115 ASSERT_TRUE(event1.has_frame_end());
1116 const auto& expectedDisplayFrameEnd = event1.frame_end();
1117 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
1118
1119 // Packet - 2 : ActualDisplayFrameStart
1120 const auto& packet2 = packets[2];
1121 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001122 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001123 ASSERT_TRUE(packet2.has_frame_timeline_event());
1124
1125 const auto& event2 = packet2.frame_timeline_event();
1126 ASSERT_TRUE(event2.has_actual_display_frame_start());
1127 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1128 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1129
1130 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1131 const auto& packet3 = packets[3];
1132 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001133 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001134 ASSERT_TRUE(packet3.has_frame_timeline_event());
1135
1136 const auto& event3 = packet3.frame_timeline_event();
1137 ASSERT_TRUE(event3.has_frame_end());
1138 const auto& actualDisplayFrameEnd = event3.frame_end();
1139 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001140}
1141
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001142TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1143 auto tracingSession = getTracingSessionForTest();
1144 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1145
1146 tracingSession->StartBlocking();
1147 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1148 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001149 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001150
Ady Abraham57a8ab42023-01-26 15:28:19 -08001151 // Add an empty surface frame so that display frame would get traced.
1152 addEmptySurfaceFrame();
1153
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001154 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001155 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001156 mFrameTimeline->setSfPresent(26, presentFence1);
1157 presentFence1->signalForTest(31);
1158
1159 int64_t traceCookie = snoopCurrentTraceCookie();
1160
1161 auto protoActualDisplayFrameStart =
1162 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1163 kSurfaceFlingerPid,
1164 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001165 false, FrameTimelineEvent::JANK_UNKNOWN,
1166 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001167 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1168
1169 addEmptyDisplayFrame();
1170 flushTrace();
1171 tracingSession->StopBlocking();
1172
1173 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1174 // Only actual timeline packets should be in the trace
1175 EXPECT_EQ(packets.size(), 2u);
1176
1177 // Packet - 0 : ActualDisplayFrameStart
1178 const auto& packet0 = packets[0];
1179 ASSERT_TRUE(packet0.has_timestamp());
1180 EXPECT_EQ(packet0.timestamp(), 20u);
1181 ASSERT_TRUE(packet0.has_frame_timeline_event());
1182
1183 const auto& event0 = packet0.frame_timeline_event();
1184 ASSERT_TRUE(event0.has_actual_display_frame_start());
1185 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1186 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1187
1188 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1189 const auto& packet1 = packets[1];
1190 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001191 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001192 ASSERT_TRUE(packet1.has_frame_timeline_event());
1193
1194 const auto& event1 = packet1.frame_timeline_event();
1195 ASSERT_TRUE(event1.has_frame_end());
1196 const auto& actualDisplayFrameEnd = event1.frame_end();
1197 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1198}
1199
Adithya Srinivasan01189672020-10-20 14:23:05 -07001200TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1201 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001202 // Layer specific increment
Edgar Arriaga631e4252023-03-02 02:11:24 +00001203 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001204 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1205 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1206
1207 tracingSession->StartBlocking();
1208 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1209 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001210
Huihong Luo3bdef862022-03-03 11:57:19 -08001211 FrameTimelineInfo ftInfo;
1212 ftInfo.vsyncId = surfaceFrameToken;
1213 ftInfo.inputEventId = sInputEventId;
1214
Adithya Srinivasan01189672020-10-20 14:23:05 -07001215 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001216 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1217 sLayerNameOne, sLayerNameOne,
1218 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001219 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001220 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1221 sLayerNameOne, sLayerNameOne,
1222 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001223 surfaceFrame1->setActualQueueTime(10);
1224 surfaceFrame1->setDropTime(15);
1225
1226 surfaceFrame2->setActualQueueTime(15);
1227 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001228
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001229 // First 2 cookies will be used by the DisplayFrame
1230 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1231
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001232 auto protoDroppedSurfaceFrameExpectedStart =
1233 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1234 displayFrameToken1, sPidOne, sLayerNameOne);
1235 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1236 auto protoDroppedSurfaceFrameActualStart =
1237 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1238 displayFrameToken1, sPidOne, sLayerNameOne,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001239 FrameTimelineEvent::PRESENT_DROPPED, true, false,
1240 FrameTimelineEvent::JANK_DROPPED,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001241 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001242 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001243
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001244 auto protoPresentedSurfaceFrameExpectedStart =
1245 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1246 displayFrameToken1, sPidOne, sLayerNameOne);
1247 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1248 auto protoPresentedSurfaceFrameActualStart =
1249 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1250 displayFrameToken1, sPidOne, sLayerNameOne,
1251 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001252 FrameTimelineEvent::JANK_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001253 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001254 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001255
1256 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001257 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001258 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1259 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001260 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001261 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001262 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001263 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001264
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001265 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001266 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001267 tracingSession->StopBlocking();
1268
1269 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001270 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1271 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001272
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001273 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001274 const auto& packet4 = packets[4];
1275 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001276 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001277 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001278
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001279 const auto& event4 = packet4.frame_timeline_event();
1280 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001281 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1282 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001283
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001284 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001285 const auto& packet5 = packets[5];
1286 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001287 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001288 ASSERT_TRUE(packet5.has_frame_timeline_event());
1289
1290 const auto& event5 = packet5.frame_timeline_event();
1291 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001292 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1293 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001294
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001295 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001296 const auto& packet6 = packets[6];
1297 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001298 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001299 ASSERT_TRUE(packet6.has_frame_timeline_event());
1300
1301 const auto& event6 = packet6.frame_timeline_event();
1302 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001303 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1304 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001305
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001306 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001307 const auto& packet7 = packets[7];
1308 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001309 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001310 ASSERT_TRUE(packet7.has_frame_timeline_event());
1311
1312 const auto& event7 = packet7.frame_timeline_event();
1313 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001314 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1315 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1316
1317 // Packet - 8 : ExpectedSurfaceFrameStart2
1318 const auto& packet8 = packets[8];
1319 ASSERT_TRUE(packet8.has_timestamp());
1320 EXPECT_EQ(packet8.timestamp(), 10u);
1321 ASSERT_TRUE(packet8.has_frame_timeline_event());
1322
1323 const auto& event8 = packet8.frame_timeline_event();
1324 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1325 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1326 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1327
1328 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1329 const auto& packet9 = packets[9];
1330 ASSERT_TRUE(packet9.has_timestamp());
1331 EXPECT_EQ(packet9.timestamp(), 25u);
1332 ASSERT_TRUE(packet9.has_frame_timeline_event());
1333
1334 const auto& event9 = packet9.frame_timeline_event();
1335 ASSERT_TRUE(event9.has_frame_end());
1336 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1337 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1338
1339 // Packet - 10 : ActualSurfaceFrameStart2
1340 const auto& packet10 = packets[10];
1341 ASSERT_TRUE(packet10.has_timestamp());
1342 EXPECT_EQ(packet10.timestamp(), 10u);
1343 ASSERT_TRUE(packet10.has_frame_timeline_event());
1344
1345 const auto& event10 = packet10.frame_timeline_event();
1346 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1347 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1348 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1349
1350 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1351 const auto& packet11 = packets[11];
1352 ASSERT_TRUE(packet11.has_timestamp());
1353 EXPECT_EQ(packet11.timestamp(), 20u);
1354 ASSERT_TRUE(packet11.has_frame_timeline_event());
1355
1356 const auto& event11 = packet11.frame_timeline_event();
1357 ASSERT_TRUE(event11.has_frame_end());
1358 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1359 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1360}
1361
Ady Abrahame43ff722022-02-15 14:44:25 -08001362TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredIsAppMissedDeadline) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001363 auto tracingSession = getTracingSessionForTest();
1364 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1365
1366 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001367 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1368 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1369 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001370 int64_t surfaceFrameToken =
1371 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1372
1373 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001374 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001375 FrameTimelineInfo ftInfo;
1376 ftInfo.vsyncId = surfaceFrameToken;
1377 ftInfo.inputEventId = 0;
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001378 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001379 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1380 sLayerNameOne, sLayerNameOne,
1381 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001382 surfaceFrame1->setActualQueueTime(appEndTime);
1383 surfaceFrame1->setAcquireFenceTime(appEndTime);
1384
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001385 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1386 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1387 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001388 int64_t displayFrameToken =
1389 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1390
1391 // First 2 cookies will be used by the DisplayFrame
1392 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1393
1394 auto protoActualSurfaceFrameStart =
1395 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1396 displayFrameToken, sPidOne, sLayerNameOne,
1397 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Ady Abrahame43ff722022-02-15 14:44:25 -08001398 false, FrameTimelineEvent::JANK_APP_DEADLINE_MISSED,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001399 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001400 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1401
1402 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001403 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001404 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1405 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1406 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1407 presentFence1->signalForTest(sfPresentTime);
1408
1409 addEmptyDisplayFrame();
1410 flushTrace();
1411 tracingSession->StopBlocking();
1412
1413 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1414 // Display Frame 4 packets + SurfaceFrame 2 packets
1415 ASSERT_EQ(packets.size(), 6u);
1416
1417 // Packet - 4 : ActualSurfaceFrameStart
1418 const auto& packet4 = packets[4];
1419 ASSERT_TRUE(packet4.has_timestamp());
1420 EXPECT_EQ(packet4.timestamp(),
1421 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1422 ASSERT_TRUE(packet4.has_frame_timeline_event());
1423
1424 const auto& event4 = packet4.frame_timeline_event();
1425 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1426 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1427 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1428
1429 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1430 const auto& packet5 = packets[5];
1431 ASSERT_TRUE(packet5.has_timestamp());
1432 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1433 ASSERT_TRUE(packet5.has_frame_timeline_event());
1434
1435 const auto& event5 = packet5.frame_timeline_event();
1436 ASSERT_TRUE(event5.has_frame_end());
1437 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001438 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001439}
1440
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001441TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDroppedFramesTracedProperly) {
1442 auto tracingSession = getTracingSessionForTest();
1443 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1444
1445 tracingSession->StartBlocking();
1446 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1447 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1448 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
1449 int64_t surfaceFrameToken =
1450 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1451
1452 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001453 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001454 FrameTimelineInfo ftInfo;
1455 ftInfo.vsyncId = surfaceFrameToken;
1456 ftInfo.inputEventId = 0;
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001457 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001458 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1459 sLayerNameOne, sLayerNameOne,
1460 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001461
1462 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(22ms).count();
1463 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1464 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
1465 int64_t displayFrameToken =
1466 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1467
1468 // First 2 cookies will be used by the DisplayFrame
1469 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1470
1471 auto protoActualSurfaceFrameStart =
1472 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1473 displayFrameToken, sPidOne, sLayerNameOne,
1474 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Edgar Arriaga631e4252023-03-02 02:11:24 +00001475 FrameTimelineEvent::JANK_DROPPED,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001476 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001477 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1478
1479 // Set up the display frame
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001480 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, RR_11, RR_11);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001481 surfaceFrame1->setDropTime(sfStartTime);
1482 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1483 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1484 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1485 presentFence1->signalForTest(sfPresentTime);
1486
1487 addEmptyDisplayFrame();
1488 flushTrace();
1489 tracingSession->StopBlocking();
1490
1491 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1492 // Display Frame 4 packets + SurfaceFrame 2 packets
1493 ASSERT_EQ(packets.size(), 6u);
1494
1495 // Packet - 4 : ActualSurfaceFrameStart
1496 const auto& packet4 = packets[4];
1497 ASSERT_TRUE(packet4.has_timestamp());
1498 EXPECT_EQ(packet4.timestamp(),
1499 static_cast<uint64_t>(sfStartTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1500 ASSERT_TRUE(packet4.has_frame_timeline_event());
1501
1502 const auto& event4 = packet4.frame_timeline_event();
1503 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1504 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1505 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1506
1507 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1508 const auto& packet5 = packets[5];
1509 ASSERT_TRUE(packet5.has_timestamp());
1510 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(sfStartTime));
1511 ASSERT_TRUE(packet5.has_frame_timeline_event());
1512
1513 const auto& event5 = packet5.frame_timeline_event();
1514 ASSERT_TRUE(event5.has_frame_end());
1515 const auto& actualSurfaceFrameEnd = event5.frame_end();
1516 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
1517}
1518
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001519// Tests for Jank classification
1520TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001521 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001522 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001523 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1524 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001525 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -08001526 FrameTimelineInfo ftInfo;
1527 ftInfo.vsyncId = surfaceFrameToken;
1528 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001529 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -08001530 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1531 sLayerNameOne, sLayerNameOne,
1532 /*isBuffer*/ true, sGameMode);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001533 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001534 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1535 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1536 mFrameTimeline->setSfPresent(26, presentFence1);
1537 auto displayFrame = getDisplayFrame(0);
1538 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1539 presentFence1->signalForTest(29);
1540
1541 // Fences haven't been flushed yet, so it should be 0
1542 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1543 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1544
1545 addEmptyDisplayFrame();
1546 displayFrame = getDisplayFrame(0);
1547
1548 // Fences have flushed, so the present timestamps should be updated
1549 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1550 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1551 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1552 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1553 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
1554}
1555
1556TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001557 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001558 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001559 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1560 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001561 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001562 mFrameTimeline->setSfPresent(26, presentFence1);
1563 auto displayFrame = getDisplayFrame(0);
1564 presentFence1->signalForTest(30);
1565
1566 // Fences for the first frame haven't been flushed yet, so it should be 0
1567 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1568
1569 // Trigger a flush by finalizing the next DisplayFrame
1570 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001571 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001572 mFrameTimeline->setSfPresent(56, presentFence2);
1573 displayFrame = getDisplayFrame(0);
1574
1575 // Fences for the first frame have flushed, so the present timestamps should be updated
1576 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1577 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1578 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1579 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1580
1581 // Fences for the second frame haven't been flushed yet, so it should be 0
1582 auto displayFrame2 = getDisplayFrame(1);
1583 presentFence2->signalForTest(65);
1584 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001585 addEmptyDisplayFrame();
1586 displayFrame2 = getDisplayFrame(1);
1587
1588 // Fences for the second frame have flushed, so the present timestamps should be updated
1589 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1590 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1591 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1592 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1593}
1594
1595TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001596 Fps vsyncRate = RR_11;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001597 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001598 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1599 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001600 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001601 mFrameTimeline->setSfPresent(26, presentFence1);
1602 auto displayFrame = getDisplayFrame(0);
1603 presentFence1->signalForTest(50);
1604
1605 // Fences for the first frame haven't been flushed yet, so it should be 0
1606 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1607
1608 // Trigger a flush by finalizing the next DisplayFrame
1609 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001610 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001611 mFrameTimeline->setSfPresent(56, presentFence2);
1612 displayFrame = getDisplayFrame(0);
1613
1614 // Fences for the first frame have flushed, so the present timestamps should be updated
1615 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1616 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1617 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1618 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1619
1620 // Fences for the second frame haven't been flushed yet, so it should be 0
1621 auto displayFrame2 = getDisplayFrame(1);
1622 presentFence2->signalForTest(75);
1623 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1624
1625 addEmptyDisplayFrame();
1626 displayFrame2 = getDisplayFrame(1);
1627
1628 // Fences for the second frame have flushed, so the present timestamps should be updated
1629 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1630 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1631 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1632 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1633}
1634
1635TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001636 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1637 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001638 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001639
1640 mFrameTimeline->setSfPresent(22, presentFence1);
1641 auto displayFrame = getDisplayFrame(0);
1642 presentFence1->signalForTest(28);
1643
1644 // Fences haven't been flushed yet, so it should be 0
1645 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1646
1647 addEmptyDisplayFrame();
1648 displayFrame = getDisplayFrame(0);
1649
1650 // Fences have flushed, so the present timestamps should be updated
1651 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1652 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1653 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1654 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1655}
1656
1657TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001658 /*
1659 * Case 1 - cpu time > vsync period but combined time > deadline > deadline -> cpudeadlinemissed
1660 * Case 2 - cpu time < vsync period but combined time > deadline -> gpudeadlinemissed
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001661 * Case 3 - previous frame ran longer -> sf_stuffing
1662 * Case 4 - Long cpu under SF stuffing -> cpudeadlinemissed
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001663 */
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001664 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001665 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001666 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1667 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001668 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1669 auto gpuFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001670 auto gpuFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1671 auto gpuFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001672 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001673 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001674 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1675 int64_t sfToken4 = mTokenManager->generateTokenForPredictions({112, 120, 120});
1676
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001677 // case 1 - cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001678 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001679 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
1680 auto displayFrame0 = getDisplayFrame(0);
1681 gpuFence1->signalForTest(36);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001682 presentFence1->signalForTest(52);
1683
1684 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001685 EXPECT_EQ(displayFrame0->getActuals().presentTime, 0);
1686
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001687 // case 2 - cpu time = 56 - 52 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001688 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001689 mFrameTimeline->setSfPresent(56, presentFence2, gpuFence2);
1690 auto displayFrame1 = getDisplayFrame(1);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001691 gpuFence2->signalForTest(76);
1692 presentFence2->signalForTest(90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001693
1694 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1695 // Fences have flushed for first displayFrame, so the present timestamps should be updated
1696 EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
1697 EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1698 EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Rachel Lee94917b32022-03-18 17:52:09 -07001699 EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001700
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001701 // case 3 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001702 mFrameTimeline->setSfWakeUp(sfToken3, 106, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001703 mFrameTimeline->setSfPresent(112, presentFence3, gpuFence3);
1704 auto displayFrame2 = getDisplayFrame(2);
1705 gpuFence3->signalForTest(116);
1706 presentFence3->signalForTest(120);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001707
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001708 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001709 // Fences have flushed for second displayFrame, so the present timestamps should be updated
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001710 EXPECT_EQ(displayFrame1->getActuals().presentTime, 90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001711 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1712 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1713 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001714
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001715 // case 4 - cpu time = 86 - 82 = 4, vsync period = 30
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001716 mFrameTimeline->setSfWakeUp(sfToken4, 120, RR_30, RR_30);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001717 mFrameTimeline->setSfPresent(140, presentFence4, gpuFence4);
1718 auto displayFrame3 = getDisplayFrame(3);
1719 gpuFence4->signalForTest(156);
1720 presentFence4->signalForTest(180);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001721
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001722 EXPECT_EQ(displayFrame3->getActuals().presentTime, 0);
1723 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1724 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1725 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1726 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1727 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerStuffing);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001728
1729 addEmptyDisplayFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001730
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001731 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1732 EXPECT_EQ(displayFrame3->getActuals().presentTime, 180);
1733 EXPECT_EQ(displayFrame3->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1734 EXPECT_EQ(displayFrame3->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1735 EXPECT_EQ(displayFrame3->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001736}
1737
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001738TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001739 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001740 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001741 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1742 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001743 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1744 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08001745 FrameTimelineInfo ftInfo;
1746 ftInfo.vsyncId = surfaceFrameToken1;
1747 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001748 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001749 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1750 sLayerNameOne, sLayerNameOne,
1751 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001752 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001753 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001754 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1755 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001756 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001757 auto displayFrame1 = getDisplayFrame(0);
1758 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1759 presentFence1->signalForTest(30);
1760
1761 // Fences for the first frame haven't been flushed yet, so it should be 0
1762 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1763 auto actuals1 = presentedSurfaceFrame1.getActuals();
1764 EXPECT_EQ(actuals1.presentTime, 0);
1765
1766 // Trigger a flush by finalizing the next DisplayFrame
1767 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08001768 FrameTimelineInfo ftInfo2;
1769 ftInfo2.vsyncId = surfaceFrameToken2;
1770 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001771 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001772 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1773 sLayerNameOne, sLayerNameOne,
1774 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001775 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001776 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001777 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1778 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001779 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001780 auto displayFrame2 = getDisplayFrame(1);
1781 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1782
1783 // Fences for the first frame have flushed, so the present timestamps should be updated
1784 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1785 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1786 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1787 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1788
1789 actuals1 = presentedSurfaceFrame1.getActuals();
1790 EXPECT_EQ(actuals1.presentTime, 30);
1791 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1792 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1793 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1794
1795 // Fences for the second frame haven't been flushed yet, so it should be 0
1796 presentFence2->signalForTest(65);
1797 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1798 auto actuals2 = presentedSurfaceFrame2.getActuals();
1799 EXPECT_EQ(actuals2.presentTime, 0);
1800
Alec Mouri363faf02021-01-29 16:34:55 -08001801 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1802
1803 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001804 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
1805 sLayerNameOne, sGameMode,
1806 JankType::PredictionError, -3, 5,
1807 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08001808
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001809 addEmptyDisplayFrame();
1810
1811 // Fences for the second frame have flushed, so the present timestamps should be updated
1812 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1813 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1814 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1815 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1816
1817 actuals2 = presentedSurfaceFrame2.getActuals();
1818 EXPECT_EQ(actuals2.presentTime, 65);
1819 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1820 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1821 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1822}
1823
1824TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001825 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001826 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001827 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1828 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001829 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1830 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08001831 FrameTimelineInfo ftInfo;
1832 ftInfo.vsyncId = surfaceFrameToken1;
1833 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001834 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001835 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1836 sLayerNameOne, sLayerNameOne,
1837 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001838 surfaceFrame1->setAcquireFenceTime(16);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001839 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001840 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1841 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1842 mFrameTimeline->setSfPresent(26, presentFence1);
1843 auto displayFrame1 = getDisplayFrame(0);
1844 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1845 presentFence1->signalForTest(50);
1846
1847 // Fences for the first frame haven't been flushed yet, so it should be 0
1848 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1849 auto actuals1 = presentedSurfaceFrame1.getActuals();
1850 EXPECT_EQ(actuals1.presentTime, 0);
1851
1852 // Trigger a flush by finalizing the next DisplayFrame
1853 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08001854 FrameTimelineInfo ftInfo2;
1855 ftInfo2.vsyncId = surfaceFrameToken2;
1856 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001857 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001858 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1859 sLayerNameOne, sLayerNameOne,
1860 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001861 surfaceFrame2->setAcquireFenceTime(36);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001862 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001863 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1864 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001865 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001866 auto displayFrame2 = getDisplayFrame(1);
1867 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1868
1869 // Fences for the first frame have flushed, so the present timestamps should be updated
1870 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1871 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1872 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1873 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1874
1875 actuals1 = presentedSurfaceFrame1.getActuals();
1876 EXPECT_EQ(actuals1.presentTime, 50);
1877 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1878 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1879 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1880
1881 // Fences for the second frame haven't been flushed yet, so it should be 0
1882 presentFence2->signalForTest(86);
1883 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1884 auto actuals2 = presentedSurfaceFrame2.getActuals();
1885 EXPECT_EQ(actuals2.presentTime, 0);
1886
Alec Mouri363faf02021-01-29 16:34:55 -08001887 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1888
1889 EXPECT_CALL(*mTimeStats,
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001890 incrementJankyFrames(TimeStats::JankyFramesInfo{RR_11, std::nullopt, sUidOne,
1891 sLayerNameOne, sGameMode,
1892 JankType::PredictionError, -3, 5,
1893 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08001894
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001895 addEmptyDisplayFrame();
1896
1897 // Fences for the second frame have flushed, so the present timestamps should be updated
1898 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1899 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1900 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1901 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1902
1903 actuals2 = presentedSurfaceFrame2.getActuals();
1904 EXPECT_EQ(actuals2.presentTime, 86);
1905 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1906 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1907 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1908}
1909
1910TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001911 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08001912
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001913 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001914 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001915 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -08001916 FrameTimelineInfo ftInfo;
1917 ftInfo.vsyncId = surfaceFrameToken1;
1918 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001919 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001920 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1921 sLayerNameOne, sLayerNameOne,
1922 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001923 surfaceFrame1->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001924 mFrameTimeline->setSfWakeUp(sfToken1, 42, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001925 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1926 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1927 mFrameTimeline->setSfPresent(46, presentFence1);
1928 auto displayFrame1 = getDisplayFrame(0);
1929 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1930 presentFence1->signalForTest(50);
1931
1932 // Fences for the first frame haven't been flushed yet, so it should be 0
1933 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1934 auto actuals1 = presentedSurfaceFrame1.getActuals();
1935 EXPECT_EQ(actuals1.presentTime, 0);
1936
1937 addEmptyDisplayFrame();
1938
1939 // Fences for the first frame have flushed, so the present timestamps should be updated
1940 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1941 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1942 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1943 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1944
1945 actuals1 = presentedSurfaceFrame1.getActuals();
1946 EXPECT_EQ(actuals1.presentTime, 50);
1947 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1948 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1949 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
1950}
1951
1952TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001953 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as only
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001954 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001955 // jank to the SurfaceFrame along with AppDeadlineMissed.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001956
Alec Mouri363faf02021-01-29 16:34:55 -08001957 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001958 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001959 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
1960 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001961 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1962 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
Huihong Luo3bdef862022-03-03 11:57:19 -08001963 FrameTimelineInfo ftInfo;
1964 ftInfo.vsyncId = surfaceFrameToken1;
1965 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001966 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001967 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1968 sLayerNameOne, sLayerNameOne,
1969 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001970 surfaceFrame1->setAcquireFenceTime(26);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001971 mFrameTimeline->setSfWakeUp(sfToken1, 32, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001972 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1973 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1974 mFrameTimeline->setSfPresent(36, presentFence1);
1975 auto displayFrame1 = getDisplayFrame(0);
1976 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1977 presentFence1->signalForTest(40);
1978
1979 // Fences for the first frame haven't been flushed yet, so it should be 0
1980 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1981 auto actuals1 = presentedSurfaceFrame1.getActuals();
1982 EXPECT_EQ(actuals1.presentTime, 0);
1983
1984 // Trigger a flush by finalizing the next DisplayFrame
1985 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08001986 FrameTimelineInfo ftInfo2;
1987 ftInfo2.vsyncId = surfaceFrameToken2;
1988 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001989 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001990 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1991 sLayerNameOne, sLayerNameOne,
1992 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001993 surfaceFrame2->setAcquireFenceTime(40);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02001994 mFrameTimeline->setSfWakeUp(sfToken2, 43, RR_11, RR_11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001995 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1996 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1997 mFrameTimeline->setSfPresent(56, presentFence2);
1998 auto displayFrame2 = getDisplayFrame(1);
1999 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2000
2001 // Fences for the first frame have flushed, so the present timestamps should be updated
2002 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
2003 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2004 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2005 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2006
2007 actuals1 = presentedSurfaceFrame1.getActuals();
2008 EXPECT_EQ(actuals1.presentTime, 40);
2009 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2010 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2011 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2012
2013 // Fences for the second frame haven't been flushed yet, so it should be 0
2014 presentFence2->signalForTest(60);
2015 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2016 auto actuals2 = presentedSurfaceFrame2.getActuals();
2017 EXPECT_EQ(actuals2.presentTime, 0);
2018
2019 addEmptyDisplayFrame();
2020
2021 // Fences for the second frame have flushed, so the present timestamps should be updated
2022 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
2023 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2024 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2025 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
2026
2027 actuals2 = presentedSurfaceFrame2.getActuals();
2028 EXPECT_EQ(actuals2.presentTime, 60);
2029 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2030 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002031 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2032 JankType::SurfaceFlingerCpuDeadlineMissed | JankType::AppDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002033}
2034
2035TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002036 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08002037 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002038 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2039 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2040 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2041
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002042 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2043 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Huihong Luo3bdef862022-03-03 11:57:19 -08002044 FrameTimelineInfo ftInfo;
2045 ftInfo.vsyncId = surfaceFrameToken1;
2046 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002047 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002048 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2049 sLayerNameOne, sLayerNameOne,
2050 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002051 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002052 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002053 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2054 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2055 mFrameTimeline->setSfPresent(56, presentFence1);
2056 auto displayFrame1 = getDisplayFrame(0);
2057 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2058 presentFence1->signalForTest(60);
2059
2060 // Fences for the first frame haven't been flushed yet, so it should be 0
2061 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2062 auto actuals1 = presentedSurfaceFrame1.getActuals();
2063 EXPECT_EQ(actuals1.presentTime, 0);
2064
2065 // Trigger a flush by finalizing the next DisplayFrame
2066 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002067 FrameTimelineInfo ftInfo2;
2068 ftInfo2.vsyncId = surfaceFrameToken2;
2069 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002070 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002071 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2072 sLayerNameOne, sLayerNameOne,
2073 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002074 surfaceFrame2->setAcquireFenceTime(84);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002075 mFrameTimeline->setSfWakeUp(sfToken2, 112, RR_30, RR_30);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002076 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2077 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2078 mFrameTimeline->setSfPresent(116, presentFence2);
2079 auto displayFrame2 = getDisplayFrame(1);
2080 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2081 presentFence2->signalForTest(120);
2082
2083 // Fences for the first frame have flushed, so the present timestamps should be updated
2084 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2085 actuals1 = presentedSurfaceFrame1.getActuals();
2086 EXPECT_EQ(actuals1.endTime, 50);
2087 EXPECT_EQ(actuals1.presentTime, 60);
2088
2089 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2090 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2091 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2092
2093 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2094 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2095 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2096
2097 // Fences for the second frame haven't been flushed yet, so it should be 0
2098 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2099 auto actuals2 = presentedSurfaceFrame2.getActuals();
2100 EXPECT_EQ(actuals2.presentTime, 0);
2101
2102 addEmptyDisplayFrame();
2103
2104 // Fences for the second frame have flushed, so the present timestamps should be updated
2105 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
2106 actuals2 = presentedSurfaceFrame2.getActuals();
2107 EXPECT_EQ(actuals2.presentTime, 120);
2108
2109 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2110 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2111 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
2112
2113 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2114 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2115 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2116 JankType::AppDeadlineMissed | JankType::BufferStuffing);
2117}
Alec Mouriadebf5c2021-01-05 12:57:36 -08002118
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002119TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
2120 // Layer specific increment
2121 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
2122 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2123 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2124 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2125
2126 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2127 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -08002128 FrameTimelineInfo ftInfo;
2129 ftInfo.vsyncId = surfaceFrameToken1;
2130 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002131 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002132 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2133 sLayerNameOne, sLayerNameOne,
2134 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002135 surfaceFrame1->setAcquireFenceTime(50);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002136 mFrameTimeline->setSfWakeUp(sfToken1, 52, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002137 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2138 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2139 mFrameTimeline->setSfPresent(56, presentFence1);
2140 auto displayFrame1 = getDisplayFrame(0);
2141 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2142 presentFence1->signalForTest(60);
2143
2144 // Fences for the first frame haven't been flushed yet, so it should be 0
2145 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2146 auto actuals1 = presentedSurfaceFrame1.getActuals();
2147 EXPECT_EQ(actuals1.presentTime, 0);
2148
2149 // Trigger a flush by finalizing the next DisplayFrame
2150 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002151 FrameTimelineInfo ftInfo2;
2152 ftInfo2.vsyncId = surfaceFrameToken2;
2153 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002154 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002155 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2156 sLayerNameOne, sLayerNameOne,
2157 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002158 surfaceFrame2->setAcquireFenceTime(80);
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002159 mFrameTimeline->setSfWakeUp(sfToken2, 82, RR_30, RR_30);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002160 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
2161 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2162 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2163 mFrameTimeline->setSfPresent(86, presentFence2);
2164 auto displayFrame2 = getDisplayFrame(1);
2165 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2166 presentFence2->signalForTest(90);
2167
2168 // Fences for the first frame have flushed, so the present timestamps should be updated
2169 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2170 actuals1 = presentedSurfaceFrame1.getActuals();
2171 EXPECT_EQ(actuals1.endTime, 50);
2172 EXPECT_EQ(actuals1.presentTime, 60);
2173
2174 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2175 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2176 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2177
2178 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2179 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2180 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2181
2182 // Fences for the second frame haven't been flushed yet, so it should be 0
2183 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2184 auto actuals2 = presentedSurfaceFrame2.getActuals();
2185 EXPECT_EQ(actuals2.presentTime, 0);
2186
2187 addEmptyDisplayFrame();
2188
2189 // Fences for the second frame have flushed, so the present timestamps should be updated
2190 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2191 actuals2 = presentedSurfaceFrame2.getActuals();
2192 EXPECT_EQ(actuals2.presentTime, 90);
2193
2194 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2195 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2196 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
2197
2198 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2199 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2200 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
2201}
2202
Rachel Lee94917b32022-03-18 17:52:09 -07002203TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent_GpuAndCpuMiss) {
2204 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2205 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2206 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2207 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2208 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2209
2210 // Case 1: cpu time = 33 - 12 = 21, vsync period = 11
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002211 mFrameTimeline->setSfWakeUp(sfToken1, 12, RR_11, RR_11);
Rachel Lee94917b32022-03-18 17:52:09 -07002212 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
2213 auto displayFrame = getDisplayFrame(0);
2214 gpuFence1->signalForTest(36);
2215 presentFence1->signalForTest(52);
2216
2217 // Fences haven't been flushed yet, so it should be 0
2218 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
2219
2220 addEmptyDisplayFrame();
2221 displayFrame = getDisplayFrame(0);
2222
2223 // Fences have flushed, so the present timestamps should be updated
2224 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
2225 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2226 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2227 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
2228
2229 // Case 2: No GPU fence so it will not use GPU composition.
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002230 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_30, RR_30);
Rachel Lee94917b32022-03-18 17:52:09 -07002231 mFrameTimeline->setSfPresent(66, presentFence2);
2232 auto displayFrame2 = getDisplayFrame(2); // 2 because of previous empty frame
2233 presentFence2->signalForTest(90);
2234
2235 // Fences for the frame haven't been flushed yet, so it should be 0
2236 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2237
2238 addEmptyDisplayFrame();
2239
2240 // Fences have flushed, so the present timestamps should be updated
2241 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2242 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2243 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2244 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
2245}
2246
Ady Abrahamfcb16862022-10-10 14:35:21 -07002247TEST_F(FrameTimelineTest, jankClassification_presentFenceError) {
2248 auto erroneousPresentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2249 auto erroneousPresentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2250 auto validPresentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2251 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2252 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2253 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({72, 80, 80});
2254
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002255 mFrameTimeline->setSfWakeUp(sfToken1, 22, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002256 mFrameTimeline->setSfPresent(26, erroneousPresentFence1);
2257
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002258 mFrameTimeline->setSfWakeUp(sfToken2, 52, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002259 mFrameTimeline->setSfPresent(60, erroneousPresentFence2);
2260
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002261 mFrameTimeline->setSfWakeUp(sfToken3, 72, RR_11, RR_11);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002262 mFrameTimeline->setSfPresent(80, validPresentFence);
2263
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002264 erroneousPresentFence2->signalForTest(2);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002265 validPresentFence->signalForTest(80);
2266
2267 addEmptyDisplayFrame();
2268
2269 {
2270 auto displayFrame = getDisplayFrame(0);
2271 EXPECT_EQ(displayFrame->getActuals().presentTime, 26);
2272 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2273 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002274 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002275 }
2276 {
2277 auto displayFrame = getDisplayFrame(1);
2278 EXPECT_EQ(displayFrame->getActuals().presentTime, 60);
2279 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2280 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
Ady Abrahamb1e10d12023-03-13 15:23:54 -07002281 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown | JankType::DisplayHAL);
Ady Abrahamfcb16862022-10-10 14:35:21 -07002282 }
2283 {
2284 auto displayFrame = getDisplayFrame(2);
2285 EXPECT_EQ(displayFrame->getActuals().presentTime, 80);
2286 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2287 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2288 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
2289 }
2290}
2291
Alec Mouriadebf5c2021-01-05 12:57:36 -08002292TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
2293 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
2294}
2295
2296TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002297 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002298
2299 auto surfaceFrame1 =
2300 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002301 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002302 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002303 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2304 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2305 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2306 presentFence1->signalForTest(oneHundredMs);
2307 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2308
2309 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2310}
2311
2312TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002313 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2314 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002315 auto surfaceFrame1 =
2316 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002317 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002318 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002319 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2320 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2321 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2322 presentFence1->signalForTest(oneHundredMs);
2323 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2324
2325 auto surfaceFrame2 =
2326 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002327 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002328 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002329 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2330 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2331 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2332 presentFence2->signalForTest(twoHundredMs);
2333 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2334
2335 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
2336}
2337
2338TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002339 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2340 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002341 auto surfaceFrame1 =
2342 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002343 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002344 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002345 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2346 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2347 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2348 presentFence1->signalForTest(oneHundredMs);
2349 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2350
2351 auto surfaceFrame2 =
2352 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002353 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002354 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002355 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2356 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2357 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2358 presentFence2->signalForTest(twoHundredMs);
2359 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2360
2361 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
2362}
2363
2364TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002365 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2366 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002367 auto surfaceFrame1 =
2368 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002369 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002370 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002371 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2372 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2373 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2374 presentFence1->signalForTest(oneHundredMs);
2375 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2376
2377 auto surfaceFrame2 =
2378 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002379 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002380 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002381 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2382 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2383 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2384 presentFence2->signalForTest(twoHundredMs);
2385 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2386
2387 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2388}
2389
2390TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002391 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2392 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2393 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2394 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2395 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002396 auto surfaceFrame1 =
2397 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002398 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002399 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002400 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2401 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2402 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2403 presentFence1->signalForTest(oneHundredMs);
2404 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2405
2406 auto surfaceFrame2 =
2407 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002408 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002409 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002410 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2411 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2412 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2413 presentFence2->signalForTest(twoHundredMs);
2414 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2415
2416 auto surfaceFrame3 =
2417 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002418 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002419 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002420 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2421 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2422 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2423 presentFence3->signalForTest(threeHundredMs);
2424 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2425
2426 auto surfaceFrame4 =
2427 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002428 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002429 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002430 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2431 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2432 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2433 presentFence4->signalForTest(fiveHundredMs);
2434 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2435
2436 auto surfaceFrame5 =
2437 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002438 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002439 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002440 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2441 // Dropped frames will be excluded from fps computation
2442 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2443 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2444 presentFence5->signalForTest(sixHundredMs);
2445 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2446
2447 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2448}
2449
ramindaniea2bb822022-06-27 19:52:10 +00002450TEST_F(FrameTimelineTest, getMinTime) {
2451 // Use SurfaceFrame::getBaseTime to test the getMinTime.
2452 FrameTimelineInfo ftInfo;
2453
2454 // Valid prediction state test.
2455 ftInfo.vsyncId = 0L;
2456 mTokenManager->generateTokenForPredictions({10});
2457 auto surfaceFrame =
2458 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2459 sLayerNameOne, sLayerNameOne,
2460 /*isBuffer*/ true, sGameMode);
2461 ASSERT_EQ(surfaceFrame->getBaseTime(), 10);
2462
2463 // Test prediction state which is not valid.
2464 ftInfo.vsyncId = FrameTimelineInfo::INVALID_VSYNC_ID;
2465 surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2466 sLayerNameOne, sLayerNameOne,
2467 /*isBuffer*/ true, sGameMode);
2468 // Start time test.
2469 surfaceFrame->setActualStartTime(200);
2470 ASSERT_EQ(surfaceFrame->getBaseTime(), 200);
2471
2472 // End time test.
2473 surfaceFrame->setAcquireFenceTime(100);
2474 ASSERT_EQ(surfaceFrame->getBaseTime(), 100);
2475
2476 // Present time test.
2477 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2478 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2479 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2480 presentFence->signalForTest(std::chrono::nanoseconds(50ns).count());
2481 mFrameTimeline->setSfPresent(50, presentFence);
2482 ASSERT_EQ(surfaceFrame->getBaseTime(), 50);
2483}
Pascal Muetschardac7bcd92023-10-03 15:05:36 +02002484
2485TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingDisplayRate) {
2486 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2487 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2488 FrameTimelineInfo ftInfo;
2489 ftInfo.vsyncId = token1;
2490 ftInfo.inputEventId = sInputEventId;
2491 auto surfaceFrame =
2492 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2493 sLayerNameOne, sLayerNameOne,
2494 /*isBuffer*/ true, sGameMode);
2495
2496 mFrameTimeline->setSfWakeUp(token1, 20, RR_30, RR_11);
2497 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2498 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2499 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2500 mFrameTimeline->setSfPresent(50, presentFence1);
2501
2502 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 11);
2503}
2504
2505TEST_F(FrameTimelineTest, surfaceFrameRenderRateUsingAppFrameRate) {
2506 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2507 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2508 FrameTimelineInfo ftInfo;
2509 ftInfo.vsyncId = token1;
2510 ftInfo.inputEventId = sInputEventId;
2511 auto surfaceFrame =
2512 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2513 sLayerNameOne, sLayerNameOne,
2514 /*isBuffer*/ true, sGameMode);
2515 surfaceFrame->setRenderRate(RR_30);
2516 mFrameTimeline->setSfWakeUp(token1, 20, RR_11, RR_11);
2517 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2518 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2519 presentFence1->signalForTest(std::chrono::nanoseconds(50ns).count());
2520 mFrameTimeline->setSfPresent(50, presentFence1);
2521
2522 EXPECT_EQ(surfaceFrame->getRenderRate().getPeriodNsecs(), 30);
2523}
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002524} // namespace android::frametimeline