blob: abd77894af27d28c9e69c6a87dc727ea189ecab6 [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;
57
Adithya Srinivasanf279e042020-08-17 14:56:27 -070058class FrameTimelineTest : public testing::Test {
59public:
60 FrameTimelineTest() {
61 const ::testing::TestInfo* const test_info =
62 ::testing::UnitTest::GetInstance()->current_test_info();
63 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
64 }
65
66 ~FrameTimelineTest() {
67 const ::testing::TestInfo* const test_info =
68 ::testing::UnitTest::GetInstance()->current_test_info();
69 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
70 }
71
Adithya Srinivasan01189672020-10-20 14:23:05 -070072 static void SetUpTestSuite() {
73 // Need to initialize tracing in process for testing, and only once per test suite.
74 perfetto::TracingInitArgs args;
75 args.backends = perfetto::kInProcessBackend;
76 perfetto::Tracing::Initialize(args);
77 }
78
Adithya Srinivasanf279e042020-08-17 14:56:27 -070079 void SetUp() override {
Ady Abraham57f8e182022-03-08 15:54:33 -080080 constexpr bool kUseBootTimeClock = true;
Alec Mouri9a29e672020-09-14 12:39:14 -070081 mTimeStats = std::make_shared<mock::TimeStats>();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000082 mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats, kSurfaceFlingerPid,
Ady Abraham57f8e182022-03-08 15:54:33 -080083 kTestThresholds, !kUseBootTimeClock);
Adithya Srinivasan01189672020-10-20 14:23:05 -070084 mFrameTimeline->registerDataSource();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070085 mTokenManager = &mFrameTimeline->mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000086 mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
Adithya Srinivasan2d736322020-10-01 16:53:48 -070087 maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +000088 maxTokens = mTokenManager->kMaxTokens;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070089 }
90
Adithya Srinivasan01189672020-10-20 14:23:05 -070091 // Each tracing session can be used for a single block of Start -> Stop.
92 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
93 perfetto::TraceConfig cfg;
94 cfg.set_duration_ms(500);
95 cfg.add_buffers()->set_size_kb(1024);
96 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
97 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
98
99 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
100 tracingSession->Setup(cfg);
101 return tracingSession;
102 }
103
104 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
105 perfetto::TracingSession* tracingSession) {
106 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
107 perfetto::protos::Trace trace;
108 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
109
110 std::vector<perfetto::protos::TracePacket> packets;
111 for (const auto& packet : trace.packet()) {
112 if (!packet.has_frame_timeline_event()) {
113 continue;
114 }
115 packets.emplace_back(packet);
116 }
117 return packets;
118 }
119
Ady Abraham57a8ab42023-01-26 15:28:19 -0800120 void addEmptySurfaceFrame() {
121 auto surfaceFrame =
122 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
123 sLayerNameOne, sLayerNameOne,
124 /*isBuffer*/ false, sGameMode);
125 mFrameTimeline->addSurfaceFrame(std::move(surfaceFrame));
126 }
127
Adithya Srinivasan01189672020-10-20 14:23:05 -0700128 void addEmptyDisplayFrame() {
129 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000130 // Trigger a flushPresentFence by calling setSfPresent for the next frame
Adithya Srinivasan01189672020-10-20 14:23:05 -0700131 mFrameTimeline->setSfPresent(2500, presentFence1);
132 }
133
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000134 void flushTokens() {
135 for (size_t i = 0; i < maxTokens; i++) {
136 mTokenManager->generateTokenForPredictions({});
137 }
138 EXPECT_EQ(getPredictions().size(), maxTokens);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700139 }
140
141 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
142 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800143 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
144 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700145 }
146
147 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
148 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
149 return mFrameTimeline->mDisplayFrames[idx];
150 }
151
152 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
153 return a.startTime == b.startTime && a.endTime == b.endTime &&
154 a.presentTime == b.presentTime;
155 }
156
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000157 const std::map<int64_t, TimelineItem>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700158 return mTokenManager->mPredictions;
159 }
160
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000161 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700162 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
163 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
164 }
165
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000166 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
167
168 void flushTrace() {
169 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
170 FrameTimelineDataSource::Trace(
171 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
172 }
173
Alec Mouri9a29e672020-09-14 12:39:14 -0700174 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700175 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
176 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000177 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700178 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700179 uint32_t* maxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000180 size_t maxTokens;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000181 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasanead17162021-02-18 02:17:37 +0000182 static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan54996e22021-06-25 22:26:45 +0000183 static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(0ns).count();
Adithya Srinivasanead17162021-02-18 02:17:37 +0000184 static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800185 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
186 kDeadlineThreshold,
187 kStartThreshold};
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700188};
189
190TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
191 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000192 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000193 flushTokens();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700194 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
195 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
196
197 // token1 should have expired
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700198 EXPECT_EQ(predictions.has_value(), false);
199
200 predictions = mTokenManager->getPredictionsForToken(token2);
201 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
202}
203
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700204TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800205 auto surfaceFrame1 =
206 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000207 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000208 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -0800209 auto surfaceFrame2 =
210 mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000211 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000212 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700213 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
214 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
215}
216
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700217TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800218 auto surfaceFrame =
219 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000220 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000221 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700222 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
223}
224
225TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
226 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000227 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -0800228 FrameTimelineInfo ftInfo;
229 ftInfo.vsyncId = token1;
230 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000231 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800232 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
233 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000234 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700235
236 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
237}
238
239TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
240 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800241 FrameTimelineInfo ftInfo;
242 ftInfo.vsyncId = token1;
243 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000244 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800245 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
246 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000247 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700248
249 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
250 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
251}
252
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000253TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
254 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
255 constexpr int32_t inputEventId = 1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800256 FrameTimelineInfo ftInfo;
257 ftInfo.vsyncId = token1;
258 ftInfo.inputEventId = inputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000259 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800260 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
261 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000262 /*isBuffer*/ true, sGameMode);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000263
264 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
265}
266
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700267TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
268 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700269 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800270 FrameTimelineInfo ftInfo;
271 ftInfo.vsyncId = token1;
272 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000273 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800274 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
275 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000276 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700277
278 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800279 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000280 surfaceFrame1->setDropTime(12);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800281 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
282 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700283 mFrameTimeline->setSfPresent(25, presentFence1);
284 presentFence1->signalForTest(30);
285
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000286 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700287
288 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
289 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000290 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
291 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700292 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
293}
294
295TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800296 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800297 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700298 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
299 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700300 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800301 FrameTimelineInfo ftInfo;
302 ftInfo.vsyncId = surfaceFrameToken1;
303 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700304 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800305 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
306 sLayerNameOne, sLayerNameOne,
307 /*isBuffer*/ true, sGameMode);
Alec Mouri9a29e672020-09-14 12:39:14 -0700308 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800309 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdTwo,
310 sLayerNameTwo, sLayerNameTwo,
311 /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800312 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800313 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
314 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
315 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
316 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700317 mFrameTimeline->setSfPresent(26, presentFence1);
318 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800319 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
320 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700321 presentFence1->signalForTest(42);
322
323 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800324 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700325 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
326 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
327
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000328 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700329
330 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800331 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700332 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
333 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100334 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
335 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700336}
337
338TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
339 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
340 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800341 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800342 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800343 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700344 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700345 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
346 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
347 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
348 int64_t sfToken = mTokenManager->generateTokenForPredictions(
349 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800350 FrameTimelineInfo ftInfo;
351 ftInfo.vsyncId = surfaceFrameToken;
352 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700353 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800354 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000355 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000356 /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800357 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800358 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
359 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700360 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
361 presentFence->signalForTest(32 + frameTimeFactor);
362 frameTimeFactor += 30;
363 }
364 auto displayFrame0 = getDisplayFrame(0);
365
366 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800367 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700368
369 // Add one more display frame
370 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
371 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
372 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
373 int64_t sfToken = mTokenManager->generateTokenForPredictions(
374 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800375 FrameTimelineInfo ftInfo;
376 ftInfo.vsyncId = surfaceFrameToken;
377 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700378 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800379 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
380 sLayerNameOne, sLayerNameOne,
381 /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800382 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800383 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
384 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700385 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
386 presentFence->signalForTest(32 + frameTimeFactor);
387 displayFrame0 = getDisplayFrame(0);
388
389 // The window should have slided by 1 now and the previous 0th display frame
390 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800391 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700392}
393
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700394TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000395 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
396 "acquireFenceAfterQueue",
397 "acquireFenceAfterQueue",
398 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700399 surfaceFrame->setActualQueueTime(123);
400 surfaceFrame->setAcquireFenceTime(456);
401 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
402}
403
404TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000405 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
406 "acquireFenceAfterQueue",
407 "acquireFenceAfterQueue",
408 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700409 surfaceFrame->setActualQueueTime(456);
410 surfaceFrame->setAcquireFenceTime(123);
411 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
412}
413
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700414TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
415 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
416 presentFence->signalForTest(2);
417
418 // Size shouldn't exceed maxDisplayFrames - 64
419 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700420 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800421 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000422 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000423 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700424 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800425 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800426 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
427 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700428 mFrameTimeline->setSfPresent(27, presentFence);
429 }
430 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
431
432 // Increase the size to 256
433 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000434 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700435
436 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700437 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800438 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000439 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000440 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700441 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800442 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800443 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
444 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700445 mFrameTimeline->setSfPresent(27, presentFence);
446 }
447 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
448
449 // Shrink the size to 128
450 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000451 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700452
453 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700454 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800455 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000456 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000457 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700458 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800459 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800460 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
461 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700462 mFrameTimeline->setSfPresent(27, presentFence);
463 }
464 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
465}
Alec Mouri9a29e672020-09-14 12:39:14 -0700466
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000467TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
468 Fps refreshRate = Fps::fromPeriodNsecs(11);
469
470 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
471 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
472 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800473 FrameTimelineInfo ftInfo;
474 ftInfo.vsyncId = surfaceFrameToken1;
475 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000476
477 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800478 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
479 sLayerNameOne, sLayerNameOne,
480 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000481 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
482 surfaceFrame1->setAcquireFenceTime(20);
483 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
484 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
485
486 mFrameTimeline->setSfPresent(59, presentFence1);
487 presentFence1->signalForTest(-1);
488 addEmptyDisplayFrame();
489
490 auto displayFrame0 = getDisplayFrame(0);
Ady Abrahamfcb16862022-10-10 14:35:21 -0700491 EXPECT_EQ(displayFrame0->getActuals().presentTime, 59);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000492 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown);
493 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
494 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
495}
496
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800497// Tests related to TimeStats
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000498TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
499 Fps refreshRate = Fps::fromPeriodNsecs(11);
500 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
501 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
502 int64_t surfaceFrameToken1 = -1;
503 int64_t sfToken1 = -1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800504 FrameTimelineInfo ftInfo;
505 ftInfo.vsyncId = surfaceFrameToken1;
506 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000507
508 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800509 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
510 sLayerNameOne, sLayerNameOne,
511 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000512 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
513 surfaceFrame1->setAcquireFenceTime(20);
514 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
515 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
516 presentFence1->signalForTest(70);
517
518 mFrameTimeline->setSfPresent(59, presentFence1);
519}
520
Alec Mouri9a29e672020-09-14 12:39:14 -0700521TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000522 Fps refreshRate = Fps::fromPeriodNsecs(11);
Alec Mouri9a29e672020-09-14 12:39:14 -0700523 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800524 incrementJankyFrames(
525 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000526 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000527 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800528 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700529 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000530 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
531 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800532 FrameTimelineInfo ftInfo;
533 ftInfo.vsyncId = surfaceFrameToken1;
534 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000535
Alec Mouri9a29e672020-09-14 12:39:14 -0700536 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800537 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
538 sLayerNameOne, sLayerNameOne,
539 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000540 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
541 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800542 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
543 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000544 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700545
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000546 mFrameTimeline->setSfPresent(62, presentFence1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700547}
548
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000549TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfGpu) {
550 Fps refreshRate = Fps::fromPeriodNsecs(11);
551 EXPECT_CALL(*mTimeStats,
552 incrementJankyFrames(
553 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000554 sLayerNameOne, sGameMode,
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000555 JankType::SurfaceFlingerGpuDeadlineMissed, 4, 10,
556 0}));
557 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
558 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
559 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
560 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800561 FrameTimelineInfo ftInfo;
562 ftInfo.vsyncId = surfaceFrameToken1;
563 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000564
565 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800566 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
567 sLayerNameOne, sLayerNameOne,
568 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000569 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
570 surfaceFrame1->setAcquireFenceTime(20);
571 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
572 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
573 gpuFence1->signalForTest(64);
574 presentFence1->signalForTest(70);
575
576 mFrameTimeline->setSfPresent(59, presentFence1, gpuFence1);
577}
578
Alec Mouri9a29e672020-09-14 12:39:14 -0700579TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800580 Fps refreshRate = Fps::fromPeriodNsecs(30);
Alec Mouri9a29e672020-09-14 12:39:14 -0700581 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800582 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000583 sLayerNameOne, sGameMode,
584 JankType::DisplayHAL, -4, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800585
Alec Mouri9a29e672020-09-14 12:39:14 -0700586 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000587 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
588 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800589 FrameTimelineInfo ftInfo;
590 ftInfo.vsyncId = surfaceFrameToken1;
591 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000592
Alec Mouri9a29e672020-09-14 12:39:14 -0700593 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800594 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
595 sLayerNameOne, sLayerNameOne,
596 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000597 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800598 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000599 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800600 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000601 presentFence1->signalForTest(90);
602 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800603 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700604}
605
606TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700607 Fps refreshRate = 11_Hz;
Alec Mouri9a29e672020-09-14 12:39:14 -0700608 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000609 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000610 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000611 JankType::AppDeadlineMissed, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000612 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700613 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000614 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
615 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800616 FrameTimelineInfo ftInfo;
617 ftInfo.vsyncId = surfaceFrameToken1;
618 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000619
Alec Mouri9a29e672020-09-14 12:39:14 -0700620 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800621 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
622 sLayerNameOne, sLayerNameOne,
623 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000624 surfaceFrame1->setAcquireFenceTime(45);
625 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700626
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800627 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
628 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000629 presentFence1->signalForTest(90);
630 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100631
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800632 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700633}
634
Adithya Srinivasanead17162021-02-18 02:17:37 +0000635TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000636 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000637 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000638 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000639 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000640 JankType::SurfaceFlingerScheduling,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000641 -4, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000642 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000643 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
644 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800645 FrameTimelineInfo ftInfo;
646 ftInfo.vsyncId = surfaceFrameToken1;
647 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000648
Adithya Srinivasanead17162021-02-18 02:17:37 +0000649 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800650 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
651 sLayerNameOne, sLayerNameOne,
652 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000653 surfaceFrame1->setAcquireFenceTime(50);
654 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000655
656 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
657 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000658 presentFence1->signalForTest(60);
659 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000660
661 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
662}
663
664TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000665 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000666 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000667 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000668 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000669 JankType::PredictionError, -4, 5,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000670 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000671 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000672 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
673 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800674 FrameTimelineInfo ftInfo;
675 ftInfo.vsyncId = surfaceFrameToken1;
676 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000677
Adithya Srinivasanead17162021-02-18 02:17:37 +0000678 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800679 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
680 sLayerNameOne, sLayerNameOne,
681 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000682 surfaceFrame1->setAcquireFenceTime(40);
683 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000684
685 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
686 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000687 presentFence1->signalForTest(65);
688 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000689
690 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
691}
692
693TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000694 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000695 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000696 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000697 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000698 JankType::BufferStuffing, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000699 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000700 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000701 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
702 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800703 FrameTimelineInfo ftInfo;
704 ftInfo.vsyncId = surfaceFrameToken1;
705 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000706
Adithya Srinivasanead17162021-02-18 02:17:37 +0000707 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800708 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
709 sLayerNameOne, sLayerNameOne,
710 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000711 surfaceFrame1->setAcquireFenceTime(40);
712 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000713
714 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000715 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000716 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000717 presentFence1->signalForTest(90);
718 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000719
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000720 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000721}
722
Alec Mouri363faf02021-01-29 16:34:55 -0800723TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000724 Fps refreshRate = Fps::fromPeriodNsecs(11);
725 Fps renderRate = Fps::fromPeriodNsecs(30);
Alec Mouri363faf02021-01-29 16:34:55 -0800726 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000727 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne,
728 sLayerNameOne, sGameMode,
729 JankType::AppDeadlineMissed, -4, 0,
730 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800731 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000732 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
733 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800734 FrameTimelineInfo ftInfo;
735 ftInfo.vsyncId = surfaceFrameToken1;
736 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000737
Alec Mouri363faf02021-01-29 16:34:55 -0800738 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800739 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
740 sLayerNameOne, sLayerNameOne,
741 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000742 surfaceFrame1->setAcquireFenceTime(45);
743 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800744
745 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
746 surfaceFrame1->setRenderRate(renderRate);
747 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000748 presentFence1->signalForTest(90);
749 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800750
751 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
752}
753
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000754TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
755 Fps refreshRate = Fps::fromPeriodNsecs(11);
756 Fps renderRate = Fps::fromPeriodNsecs(30);
757
758 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000759 incrementJankyFrames(
760 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000761 sGameMode,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000762 JankType::Unknown | JankType::AppDeadlineMissed,
Adithya Srinivasande272452021-04-10 00:21:00 +0000763 0, 0, 25}));
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000764 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
765 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
766 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800767 FrameTimelineInfo ftInfo;
768 ftInfo.vsyncId = surfaceFrameToken1;
769 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000770
771 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800772 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
773 sLayerNameOne, sLayerNameOne,
774 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000775 surfaceFrame1->setAcquireFenceTime(45);
776 // Trigger a prediction expiry
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000777 flushTokens();
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000778 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
779
780 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
781 surfaceFrame1->setRenderRate(renderRate);
782 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
783 presentFence1->signalForTest(90);
784 mFrameTimeline->setSfPresent(86, presentFence1);
785
786 auto displayFrame = getDisplayFrame(0);
787 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
788 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
789 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
790 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
791
792 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000793 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000794}
795
Adithya Srinivasan01189672020-10-20 14:23:05 -0700796/*
797 * Tracing Tests
798 *
799 * Trace packets are flushed all the way only when the next packet is traced.
800 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
801 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
802 * will have additional empty frames created for this reason.
803 */
804TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
805 auto tracingSession = getTracingSessionForTest();
806 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700807 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800808 FrameTimelineInfo ftInfo;
809 ftInfo.vsyncId = token1;
810 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000811 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800812 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
813 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000814 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700815
816 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800817 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800818 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
819 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700820 mFrameTimeline->setSfPresent(25, presentFence1);
821 presentFence1->signalForTest(30);
822
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000823 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700824
825 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000826 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700827}
828
829TEST_F(FrameTimelineTest, tracing_sanityTest) {
830 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800831 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800832 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700833 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700834
835 tracingSession->StartBlocking();
836 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
837 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800838 FrameTimelineInfo ftInfo;
839 ftInfo.vsyncId = token1;
840 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000841 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800842 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
843 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000844 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700845
846 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800847 mFrameTimeline->setSfWakeUp(token2, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800848 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
849 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700850 mFrameTimeline->setSfPresent(25, presentFence1);
851 presentFence1->signalForTest(30);
852
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000853 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000854 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700855 tracingSession->StopBlocking();
856
857 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000858 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000859 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700860}
861
862TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
863 auto tracingSession = getTracingSessionForTest();
864 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700865
866 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700867
868 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800869 mFrameTimeline->setSfWakeUp(-1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700870 mFrameTimeline->setSfPresent(25, presentFence1);
871 presentFence1->signalForTest(30);
872
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000873 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000874 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700875 tracingSession->StopBlocking();
876
877 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000878 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700879}
880
881TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
882 auto tracingSession = getTracingSessionForTest();
883 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700884
885 tracingSession->StartBlocking();
886 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -0800887 auto surfaceFrame1 =
888 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000889 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000890 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700891
892 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800893 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800894 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
895 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700896 mFrameTimeline->setSfPresent(25, presentFence1);
897 presentFence1->signalForTest(30);
898
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000899 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000900 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700901 tracingSession->StopBlocking();
902
903 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000904 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
905 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000906 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700907}
908
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000909ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
910 pid_t pid) {
911 ProtoExpectedDisplayFrameStart proto;
912 proto.set_cookie(cookie);
913 proto.set_token(token);
914 proto.set_pid(pid);
915 return proto;
916}
917
918ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
919 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000920 bool gpuComposition, ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000921 ProtoActualDisplayFrameStart proto;
922 proto.set_cookie(cookie);
923 proto.set_token(token);
924 proto.set_pid(pid);
925 proto.set_present_type(presentType);
926 proto.set_on_time_finish(onTimeFinish);
927 proto.set_gpu_composition(gpuComposition);
928 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000929 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000930 return proto;
931}
932
933ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
934 int64_t displayFrameToken,
935 pid_t pid,
936 std::string layerName) {
937 ProtoExpectedSurfaceFrameStart proto;
938 proto.set_cookie(cookie);
939 proto.set_token(token);
940 proto.set_display_frame_token(displayFrameToken);
941 proto.set_pid(pid);
942 proto.set_layer_name(layerName);
943 return proto;
944}
945
946ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
947 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
948 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +0000949 ProtoJankType jankType, ProtoPredictionType predictionType, bool isBuffer) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000950 ProtoActualSurfaceFrameStart proto;
951 proto.set_cookie(cookie);
952 proto.set_token(token);
953 proto.set_display_frame_token(displayFrameToken);
954 proto.set_pid(pid);
955 proto.set_layer_name(layerName);
956 proto.set_present_type(presentType);
957 proto.set_on_time_finish(onTimeFinish);
958 proto.set_gpu_composition(gpuComposition);
959 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000960 proto.set_prediction_type(predictionType);
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +0000961 proto.set_is_buffer(isBuffer);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000962 return proto;
963}
964
965ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
966 ProtoFrameEnd proto;
967 proto.set_cookie(cookie);
968 return proto;
969}
970
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000971void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
972 const ProtoExpectedDisplayFrameStart& source) {
973 ASSERT_TRUE(received.has_cookie());
974 EXPECT_EQ(received.cookie(), source.cookie());
975
Adithya Srinivasan01189672020-10-20 14:23:05 -0700976 ASSERT_TRUE(received.has_token());
977 EXPECT_EQ(received.token(), source.token());
978
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000979 ASSERT_TRUE(received.has_pid());
980 EXPECT_EQ(received.pid(), source.pid());
981}
982
983void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
984 const ProtoActualDisplayFrameStart& source) {
985 ASSERT_TRUE(received.has_cookie());
986 EXPECT_EQ(received.cookie(), source.cookie());
987
988 ASSERT_TRUE(received.has_token());
989 EXPECT_EQ(received.token(), source.token());
990
991 ASSERT_TRUE(received.has_pid());
992 EXPECT_EQ(received.pid(), source.pid());
993
Adithya Srinivasan01189672020-10-20 14:23:05 -0700994 ASSERT_TRUE(received.has_present_type());
995 EXPECT_EQ(received.present_type(), source.present_type());
996 ASSERT_TRUE(received.has_on_time_finish());
997 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
998 ASSERT_TRUE(received.has_gpu_composition());
999 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1000 ASSERT_TRUE(received.has_jank_type());
1001 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001002 ASSERT_TRUE(received.has_prediction_type());
1003 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001004}
1005
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001006void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
1007 const ProtoExpectedSurfaceFrameStart& source) {
1008 ASSERT_TRUE(received.has_cookie());
1009 EXPECT_EQ(received.cookie(), source.cookie());
1010
Adithya Srinivasan01189672020-10-20 14:23:05 -07001011 ASSERT_TRUE(received.has_token());
1012 EXPECT_EQ(received.token(), source.token());
1013
1014 ASSERT_TRUE(received.has_display_frame_token());
1015 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1016
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001017 ASSERT_TRUE(received.has_pid());
1018 EXPECT_EQ(received.pid(), source.pid());
1019
1020 ASSERT_TRUE(received.has_layer_name());
1021 EXPECT_EQ(received.layer_name(), source.layer_name());
1022}
1023
1024void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
1025 const ProtoActualSurfaceFrameStart& source) {
1026 ASSERT_TRUE(received.has_cookie());
1027 EXPECT_EQ(received.cookie(), source.cookie());
1028
1029 ASSERT_TRUE(received.has_token());
1030 EXPECT_EQ(received.token(), source.token());
1031
1032 ASSERT_TRUE(received.has_display_frame_token());
1033 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1034
1035 ASSERT_TRUE(received.has_pid());
1036 EXPECT_EQ(received.pid(), source.pid());
1037
1038 ASSERT_TRUE(received.has_layer_name());
1039 EXPECT_EQ(received.layer_name(), source.layer_name());
1040
Adithya Srinivasan01189672020-10-20 14:23:05 -07001041 ASSERT_TRUE(received.has_present_type());
1042 EXPECT_EQ(received.present_type(), source.present_type());
1043 ASSERT_TRUE(received.has_on_time_finish());
1044 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1045 ASSERT_TRUE(received.has_gpu_composition());
1046 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1047 ASSERT_TRUE(received.has_jank_type());
1048 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001049 ASSERT_TRUE(received.has_prediction_type());
1050 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001051 ASSERT_TRUE(received.has_is_buffer());
1052 EXPECT_EQ(received.is_buffer(), source.is_buffer());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001053}
Adithya Srinivasan01189672020-10-20 14:23:05 -07001054
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001055void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
1056 ASSERT_TRUE(received.has_cookie());
1057 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001058}
1059
1060TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
1061 auto tracingSession = getTracingSessionForTest();
1062 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001063
1064 tracingSession->StartBlocking();
Ady Abraham57a8ab42023-01-26 15:28:19 -08001065
1066 // Add an empty surface frame so that display frame would get traced.
1067 addEmptySurfaceFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001068 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001069
1070 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -08001071 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -07001072 mFrameTimeline->setSfPresent(26, presentFence1);
1073 presentFence1->signalForTest(31);
1074
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001075 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001076 auto protoExpectedDisplayFrameStart =
1077 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1078 kSurfaceFlingerPid);
1079 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1080 auto protoActualDisplayFrameStart =
1081 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
1082 kSurfaceFlingerPid,
1083 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001084 FrameTimelineEvent::JANK_NONE,
1085 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001086 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001087
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001088 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001089 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001090 tracingSession->StopBlocking();
1091
1092 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001093 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001094
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001095 // Packet - 0 : ExpectedDisplayFrameStart
1096 const auto& packet0 = packets[0];
1097 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001098 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001099 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001100
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001101 const auto& event0 = packet0.frame_timeline_event();
1102 ASSERT_TRUE(event0.has_expected_display_frame_start());
1103 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
1104 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
1105
1106 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
1107 const auto& packet1 = packets[1];
1108 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001109 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001110 ASSERT_TRUE(packet1.has_frame_timeline_event());
1111
1112 const auto& event1 = packet1.frame_timeline_event();
1113 ASSERT_TRUE(event1.has_frame_end());
1114 const auto& expectedDisplayFrameEnd = event1.frame_end();
1115 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
1116
1117 // Packet - 2 : ActualDisplayFrameStart
1118 const auto& packet2 = packets[2];
1119 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001120 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001121 ASSERT_TRUE(packet2.has_frame_timeline_event());
1122
1123 const auto& event2 = packet2.frame_timeline_event();
1124 ASSERT_TRUE(event2.has_actual_display_frame_start());
1125 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1126 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1127
1128 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1129 const auto& packet3 = packets[3];
1130 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001131 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001132 ASSERT_TRUE(packet3.has_frame_timeline_event());
1133
1134 const auto& event3 = packet3.frame_timeline_event();
1135 ASSERT_TRUE(event3.has_frame_end());
1136 const auto& actualDisplayFrameEnd = event3.frame_end();
1137 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001138}
1139
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001140TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1141 auto tracingSession = getTracingSessionForTest();
1142 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1143
1144 tracingSession->StartBlocking();
1145 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1146 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001147 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001148
Ady Abraham57a8ab42023-01-26 15:28:19 -08001149 // Add an empty surface frame so that display frame would get traced.
1150 addEmptySurfaceFrame();
1151
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001152 // Set up the display frame
1153 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
1154 mFrameTimeline->setSfPresent(26, presentFence1);
1155 presentFence1->signalForTest(31);
1156
1157 int64_t traceCookie = snoopCurrentTraceCookie();
1158
1159 auto protoActualDisplayFrameStart =
1160 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1161 kSurfaceFlingerPid,
1162 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001163 false, FrameTimelineEvent::JANK_UNKNOWN,
1164 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001165 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1166
1167 addEmptyDisplayFrame();
1168 flushTrace();
1169 tracingSession->StopBlocking();
1170
1171 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1172 // Only actual timeline packets should be in the trace
1173 EXPECT_EQ(packets.size(), 2u);
1174
1175 // Packet - 0 : ActualDisplayFrameStart
1176 const auto& packet0 = packets[0];
1177 ASSERT_TRUE(packet0.has_timestamp());
1178 EXPECT_EQ(packet0.timestamp(), 20u);
1179 ASSERT_TRUE(packet0.has_frame_timeline_event());
1180
1181 const auto& event0 = packet0.frame_timeline_event();
1182 ASSERT_TRUE(event0.has_actual_display_frame_start());
1183 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1184 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1185
1186 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1187 const auto& packet1 = packets[1];
1188 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001189 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001190 ASSERT_TRUE(packet1.has_frame_timeline_event());
1191
1192 const auto& event1 = packet1.frame_timeline_event();
1193 ASSERT_TRUE(event1.has_frame_end());
1194 const auto& actualDisplayFrameEnd = event1.frame_end();
1195 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1196}
1197
Adithya Srinivasan01189672020-10-20 14:23:05 -07001198TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1199 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001200 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001201 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -07001202 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1203 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1204
1205 tracingSession->StartBlocking();
1206 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1207 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001208
Huihong Luo3bdef862022-03-03 11:57:19 -08001209 FrameTimelineInfo ftInfo;
1210 ftInfo.vsyncId = surfaceFrameToken;
1211 ftInfo.inputEventId = sInputEventId;
1212
Adithya Srinivasan01189672020-10-20 14:23:05 -07001213 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001214 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1215 sLayerNameOne, sLayerNameOne,
1216 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001217 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001218 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1219 sLayerNameOne, sLayerNameOne,
1220 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001221 surfaceFrame1->setActualQueueTime(10);
1222 surfaceFrame1->setDropTime(15);
1223
1224 surfaceFrame2->setActualQueueTime(15);
1225 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001226
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001227 // First 2 cookies will be used by the DisplayFrame
1228 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1229
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001230 auto protoDroppedSurfaceFrameExpectedStart =
1231 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1232 displayFrameToken1, sPidOne, sLayerNameOne);
1233 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1234 auto protoDroppedSurfaceFrameActualStart =
1235 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1236 displayFrameToken1, sPidOne, sLayerNameOne,
1237 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001238 FrameTimelineEvent::JANK_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001239 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001240 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001241
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001242 auto protoPresentedSurfaceFrameExpectedStart =
1243 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1244 displayFrameToken1, sPidOne, sLayerNameOne);
1245 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1246 auto protoPresentedSurfaceFrameActualStart =
1247 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1248 displayFrameToken1, sPidOne, sLayerNameOne,
1249 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001250 FrameTimelineEvent::JANK_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001251 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001252 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001253
1254 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -08001255 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001256 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1257 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001258 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001259 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001260 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001261 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001262
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001263 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001264 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001265 tracingSession->StopBlocking();
1266
1267 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001268 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1269 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001270
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001271 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001272 const auto& packet4 = packets[4];
1273 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001274 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001275 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001276
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001277 const auto& event4 = packet4.frame_timeline_event();
1278 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001279 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1280 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001281
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001282 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001283 const auto& packet5 = packets[5];
1284 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001285 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001286 ASSERT_TRUE(packet5.has_frame_timeline_event());
1287
1288 const auto& event5 = packet5.frame_timeline_event();
1289 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001290 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1291 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001292
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001293 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001294 const auto& packet6 = packets[6];
1295 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001296 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001297 ASSERT_TRUE(packet6.has_frame_timeline_event());
1298
1299 const auto& event6 = packet6.frame_timeline_event();
1300 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001301 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1302 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001303
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001304 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001305 const auto& packet7 = packets[7];
1306 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001307 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001308 ASSERT_TRUE(packet7.has_frame_timeline_event());
1309
1310 const auto& event7 = packet7.frame_timeline_event();
1311 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001312 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1313 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1314
1315 // Packet - 8 : ExpectedSurfaceFrameStart2
1316 const auto& packet8 = packets[8];
1317 ASSERT_TRUE(packet8.has_timestamp());
1318 EXPECT_EQ(packet8.timestamp(), 10u);
1319 ASSERT_TRUE(packet8.has_frame_timeline_event());
1320
1321 const auto& event8 = packet8.frame_timeline_event();
1322 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1323 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1324 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1325
1326 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1327 const auto& packet9 = packets[9];
1328 ASSERT_TRUE(packet9.has_timestamp());
1329 EXPECT_EQ(packet9.timestamp(), 25u);
1330 ASSERT_TRUE(packet9.has_frame_timeline_event());
1331
1332 const auto& event9 = packet9.frame_timeline_event();
1333 ASSERT_TRUE(event9.has_frame_end());
1334 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1335 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1336
1337 // Packet - 10 : ActualSurfaceFrameStart2
1338 const auto& packet10 = packets[10];
1339 ASSERT_TRUE(packet10.has_timestamp());
1340 EXPECT_EQ(packet10.timestamp(), 10u);
1341 ASSERT_TRUE(packet10.has_frame_timeline_event());
1342
1343 const auto& event10 = packet10.frame_timeline_event();
1344 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1345 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1346 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1347
1348 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1349 const auto& packet11 = packets[11];
1350 ASSERT_TRUE(packet11.has_timestamp());
1351 EXPECT_EQ(packet11.timestamp(), 20u);
1352 ASSERT_TRUE(packet11.has_frame_timeline_event());
1353
1354 const auto& event11 = packet11.frame_timeline_event();
1355 ASSERT_TRUE(event11.has_frame_end());
1356 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1357 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1358}
1359
Ady Abrahame43ff722022-02-15 14:44:25 -08001360TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredIsAppMissedDeadline) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001361 auto tracingSession = getTracingSessionForTest();
1362 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1363
1364 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001365 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1366 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1367 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001368 int64_t surfaceFrameToken =
1369 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1370
1371 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001372 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001373 FrameTimelineInfo ftInfo;
1374 ftInfo.vsyncId = surfaceFrameToken;
1375 ftInfo.inputEventId = 0;
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001376 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001377 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1378 sLayerNameOne, sLayerNameOne,
1379 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001380 surfaceFrame1->setActualQueueTime(appEndTime);
1381 surfaceFrame1->setAcquireFenceTime(appEndTime);
1382
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001383 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1384 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1385 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001386 int64_t displayFrameToken =
1387 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1388
1389 // First 2 cookies will be used by the DisplayFrame
1390 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1391
1392 auto protoActualSurfaceFrameStart =
1393 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1394 displayFrameToken, sPidOne, sLayerNameOne,
1395 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Ady Abrahame43ff722022-02-15 14:44:25 -08001396 false, FrameTimelineEvent::JANK_APP_DEADLINE_MISSED,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001397 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001398 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1399
1400 // Set up the display frame
1401 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1402 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1403 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1404 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1405 presentFence1->signalForTest(sfPresentTime);
1406
1407 addEmptyDisplayFrame();
1408 flushTrace();
1409 tracingSession->StopBlocking();
1410
1411 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1412 // Display Frame 4 packets + SurfaceFrame 2 packets
1413 ASSERT_EQ(packets.size(), 6u);
1414
1415 // Packet - 4 : ActualSurfaceFrameStart
1416 const auto& packet4 = packets[4];
1417 ASSERT_TRUE(packet4.has_timestamp());
1418 EXPECT_EQ(packet4.timestamp(),
1419 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1420 ASSERT_TRUE(packet4.has_frame_timeline_event());
1421
1422 const auto& event4 = packet4.frame_timeline_event();
1423 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1424 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1425 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1426
1427 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1428 const auto& packet5 = packets[5];
1429 ASSERT_TRUE(packet5.has_timestamp());
1430 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1431 ASSERT_TRUE(packet5.has_frame_timeline_event());
1432
1433 const auto& event5 = packet5.frame_timeline_event();
1434 ASSERT_TRUE(event5.has_frame_end());
1435 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001436 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001437}
1438
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001439TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDroppedFramesTracedProperly) {
1440 auto tracingSession = getTracingSessionForTest();
1441 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1442
1443 tracingSession->StartBlocking();
1444 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1445 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1446 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
1447 int64_t surfaceFrameToken =
1448 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1449
1450 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001451 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001452 FrameTimelineInfo ftInfo;
1453 ftInfo.vsyncId = surfaceFrameToken;
1454 ftInfo.inputEventId = 0;
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001455 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001456 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1457 sLayerNameOne, sLayerNameOne,
1458 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001459
1460 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(22ms).count();
1461 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1462 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
1463 int64_t displayFrameToken =
1464 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1465
1466 // First 2 cookies will be used by the DisplayFrame
1467 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1468
1469 auto protoActualSurfaceFrameStart =
1470 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1471 displayFrameToken, sPidOne, sLayerNameOne,
1472 FrameTimelineEvent::PRESENT_DROPPED, false, false,
1473 FrameTimelineEvent::JANK_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001474 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001475 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1476
1477 // Set up the display frame
1478 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1479 surfaceFrame1->setDropTime(sfStartTime);
1480 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1481 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1482 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1483 presentFence1->signalForTest(sfPresentTime);
1484
1485 addEmptyDisplayFrame();
1486 flushTrace();
1487 tracingSession->StopBlocking();
1488
1489 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1490 // Display Frame 4 packets + SurfaceFrame 2 packets
1491 ASSERT_EQ(packets.size(), 6u);
1492
1493 // Packet - 4 : ActualSurfaceFrameStart
1494 const auto& packet4 = packets[4];
1495 ASSERT_TRUE(packet4.has_timestamp());
1496 EXPECT_EQ(packet4.timestamp(),
1497 static_cast<uint64_t>(sfStartTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1498 ASSERT_TRUE(packet4.has_frame_timeline_event());
1499
1500 const auto& event4 = packet4.frame_timeline_event();
1501 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1502 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1503 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1504
1505 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1506 const auto& packet5 = packets[5];
1507 ASSERT_TRUE(packet5.has_timestamp());
1508 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(sfStartTime));
1509 ASSERT_TRUE(packet5.has_frame_timeline_event());
1510
1511 const auto& event5 = packet5.frame_timeline_event();
1512 ASSERT_TRUE(event5.has_frame_end());
1513 const auto& actualSurfaceFrameEnd = event5.frame_end();
1514 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
1515}
1516
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001517// Tests for Jank classification
1518TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001519 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001520 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001521 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1522 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001523 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -08001524 FrameTimelineInfo ftInfo;
1525 ftInfo.vsyncId = surfaceFrameToken;
1526 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001527 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -08001528 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1529 sLayerNameOne, sLayerNameOne,
1530 /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001531 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001532 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1533 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1534 mFrameTimeline->setSfPresent(26, presentFence1);
1535 auto displayFrame = getDisplayFrame(0);
1536 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1537 presentFence1->signalForTest(29);
1538
1539 // Fences haven't been flushed yet, so it should be 0
1540 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1541 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1542
1543 addEmptyDisplayFrame();
1544 displayFrame = getDisplayFrame(0);
1545
1546 // Fences have flushed, so the present timestamps should be updated
1547 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1548 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1549 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1550 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1551 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
1552}
1553
1554TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001555 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001556 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001557 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1558 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001559 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001560 mFrameTimeline->setSfPresent(26, presentFence1);
1561 auto displayFrame = getDisplayFrame(0);
1562 presentFence1->signalForTest(30);
1563
1564 // Fences for the first frame haven't been flushed yet, so it should be 0
1565 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1566
1567 // Trigger a flush by finalizing the next DisplayFrame
1568 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001569 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001570 mFrameTimeline->setSfPresent(56, presentFence2);
1571 displayFrame = getDisplayFrame(0);
1572
1573 // Fences for the first frame have flushed, so the present timestamps should be updated
1574 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1575 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1576 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1577 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1578
1579 // Fences for the second frame haven't been flushed yet, so it should be 0
1580 auto displayFrame2 = getDisplayFrame(1);
1581 presentFence2->signalForTest(65);
1582 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001583 addEmptyDisplayFrame();
1584 displayFrame2 = getDisplayFrame(1);
1585
1586 // Fences for the second frame have flushed, so the present timestamps should be updated
1587 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1588 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1589 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1590 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1591}
1592
1593TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001594 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001595 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001596 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1597 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001598 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001599 mFrameTimeline->setSfPresent(26, presentFence1);
1600 auto displayFrame = getDisplayFrame(0);
1601 presentFence1->signalForTest(50);
1602
1603 // Fences for the first frame haven't been flushed yet, so it should be 0
1604 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1605
1606 // Trigger a flush by finalizing the next DisplayFrame
1607 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001608 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001609 mFrameTimeline->setSfPresent(56, presentFence2);
1610 displayFrame = getDisplayFrame(0);
1611
1612 // Fences for the first frame have flushed, so the present timestamps should be updated
1613 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1614 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1615 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1616 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1617
1618 // Fences for the second frame haven't been flushed yet, so it should be 0
1619 auto displayFrame2 = getDisplayFrame(1);
1620 presentFence2->signalForTest(75);
1621 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1622
1623 addEmptyDisplayFrame();
1624 displayFrame2 = getDisplayFrame(1);
1625
1626 // Fences for the second frame have flushed, so the present timestamps should be updated
1627 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1628 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1629 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1630 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1631}
1632
1633TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001634 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1635 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001636 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001637
1638 mFrameTimeline->setSfPresent(22, presentFence1);
1639 auto displayFrame = getDisplayFrame(0);
1640 presentFence1->signalForTest(28);
1641
1642 // Fences haven't been flushed yet, so it should be 0
1643 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1644
1645 addEmptyDisplayFrame();
1646 displayFrame = getDisplayFrame(0);
1647
1648 // Fences have flushed, so the present timestamps should be updated
1649 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1650 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1651 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1652 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1653}
1654
1655TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001656 /*
1657 * Case 1 - cpu time > vsync period but combined time > deadline > deadline -> cpudeadlinemissed
1658 * Case 2 - cpu time < vsync period but combined time > deadline -> gpudeadlinemissed
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001659 * Case 3 - previous frame ran longer -> sf_stuffing
1660 * Case 4 - Long cpu under SF stuffing -> cpudeadlinemissed
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001661 */
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001662 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001663 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001664 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1665 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001666 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1667 auto gpuFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001668 auto gpuFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1669 auto gpuFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001670 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001671 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001672 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1673 int64_t sfToken4 = mTokenManager->generateTokenForPredictions({112, 120, 120});
1674
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001675 // case 1 - cpu time = 33 - 12 = 21, vsync period = 11
Alec Mouri7d436ec2021-01-27 20:40:50 -08001676 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001677 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
1678 auto displayFrame0 = getDisplayFrame(0);
1679 gpuFence1->signalForTest(36);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001680 presentFence1->signalForTest(52);
1681
1682 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001683 EXPECT_EQ(displayFrame0->getActuals().presentTime, 0);
1684
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001685 // case 2 - cpu time = 56 - 52 = 4, vsync period = 30
1686 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001687 mFrameTimeline->setSfPresent(56, presentFence2, gpuFence2);
1688 auto displayFrame1 = getDisplayFrame(1);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001689 gpuFence2->signalForTest(76);
1690 presentFence2->signalForTest(90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001691
1692 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1693 // Fences have flushed for first displayFrame, so the present timestamps should be updated
1694 EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
1695 EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1696 EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Rachel Lee94917b32022-03-18 17:52:09 -07001697 EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001698
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001699 // case 3 - cpu time = 86 - 82 = 4, vsync period = 30
1700 mFrameTimeline->setSfWakeUp(sfToken3, 106, Fps::fromPeriodNsecs(30));
1701 mFrameTimeline->setSfPresent(112, presentFence3, gpuFence3);
1702 auto displayFrame2 = getDisplayFrame(2);
1703 gpuFence3->signalForTest(116);
1704 presentFence3->signalForTest(120);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001705
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001706 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001707 // Fences have flushed for second displayFrame, so the present timestamps should be updated
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001708 EXPECT_EQ(displayFrame1->getActuals().presentTime, 90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001709 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1710 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1711 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001712
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001713 // case 4 - cpu time = 86 - 82 = 4, vsync period = 30
1714 mFrameTimeline->setSfWakeUp(sfToken4, 120, Fps::fromPeriodNsecs(30));
1715 mFrameTimeline->setSfPresent(140, presentFence4, gpuFence4);
1716 auto displayFrame3 = getDisplayFrame(3);
1717 gpuFence4->signalForTest(156);
1718 presentFence4->signalForTest(180);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001719
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001720 EXPECT_EQ(displayFrame3->getActuals().presentTime, 0);
1721 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1722 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1723 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1724 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1725 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerStuffing);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001726
1727 addEmptyDisplayFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001728
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001729 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1730 EXPECT_EQ(displayFrame3->getActuals().presentTime, 180);
1731 EXPECT_EQ(displayFrame3->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1732 EXPECT_EQ(displayFrame3->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1733 EXPECT_EQ(displayFrame3->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001734}
1735
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001736TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001737 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001738 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001739 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1740 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001741 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1742 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08001743 FrameTimelineInfo ftInfo;
1744 ftInfo.vsyncId = surfaceFrameToken1;
1745 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001746 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001747 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1748 sLayerNameOne, sLayerNameOne,
1749 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001750 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001751 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001752 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1753 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001754 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001755 auto displayFrame1 = getDisplayFrame(0);
1756 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1757 presentFence1->signalForTest(30);
1758
1759 // Fences for the first frame haven't been flushed yet, so it should be 0
1760 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1761 auto actuals1 = presentedSurfaceFrame1.getActuals();
1762 EXPECT_EQ(actuals1.presentTime, 0);
1763
1764 // Trigger a flush by finalizing the next DisplayFrame
1765 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08001766 FrameTimelineInfo ftInfo2;
1767 ftInfo2.vsyncId = surfaceFrameToken2;
1768 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001769 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001770 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1771 sLayerNameOne, sLayerNameOne,
1772 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001773 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001774 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001775 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1776 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001777 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001778 auto displayFrame2 = getDisplayFrame(1);
1779 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1780
1781 // Fences for the first frame have flushed, so the present timestamps should be updated
1782 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1783 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1784 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1785 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1786
1787 actuals1 = presentedSurfaceFrame1.getActuals();
1788 EXPECT_EQ(actuals1.presentTime, 30);
1789 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1790 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1791 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1792
1793 // Fences for the second frame haven't been flushed yet, so it should be 0
1794 presentFence2->signalForTest(65);
1795 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1796 auto actuals2 = presentedSurfaceFrame2.getActuals();
1797 EXPECT_EQ(actuals2.presentTime, 0);
1798
Alec Mouri363faf02021-01-29 16:34:55 -08001799 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1800
1801 EXPECT_CALL(*mTimeStats,
1802 incrementJankyFrames(
1803 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001804 sLayerNameOne, sGameMode,
1805 JankType::PredictionError, -3, 5, 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08001806
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001807 addEmptyDisplayFrame();
1808
1809 // Fences for the second frame have flushed, so the present timestamps should be updated
1810 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1811 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1812 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1813 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1814
1815 actuals2 = presentedSurfaceFrame2.getActuals();
1816 EXPECT_EQ(actuals2.presentTime, 65);
1817 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1818 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1819 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1820}
1821
1822TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001823 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001824 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001825 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1826 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001827 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1828 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08001829 FrameTimelineInfo ftInfo;
1830 ftInfo.vsyncId = surfaceFrameToken1;
1831 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001832 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001833 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1834 sLayerNameOne, sLayerNameOne,
1835 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001836 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001837 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001838 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1839 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1840 mFrameTimeline->setSfPresent(26, presentFence1);
1841 auto displayFrame1 = getDisplayFrame(0);
1842 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1843 presentFence1->signalForTest(50);
1844
1845 // Fences for the first frame haven't been flushed yet, so it should be 0
1846 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1847 auto actuals1 = presentedSurfaceFrame1.getActuals();
1848 EXPECT_EQ(actuals1.presentTime, 0);
1849
1850 // Trigger a flush by finalizing the next DisplayFrame
1851 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08001852 FrameTimelineInfo ftInfo2;
1853 ftInfo2.vsyncId = surfaceFrameToken2;
1854 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001855 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001856 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1857 sLayerNameOne, sLayerNameOne,
1858 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001859 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001860 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001861 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1862 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001863 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001864 auto displayFrame2 = getDisplayFrame(1);
1865 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1866
1867 // Fences for the first frame have flushed, so the present timestamps should be updated
1868 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1869 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1870 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1871 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1872
1873 actuals1 = presentedSurfaceFrame1.getActuals();
1874 EXPECT_EQ(actuals1.presentTime, 50);
1875 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1876 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1877 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1878
1879 // Fences for the second frame haven't been flushed yet, so it should be 0
1880 presentFence2->signalForTest(86);
1881 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1882 auto actuals2 = presentedSurfaceFrame2.getActuals();
1883 EXPECT_EQ(actuals2.presentTime, 0);
1884
Alec Mouri363faf02021-01-29 16:34:55 -08001885 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1886
1887 EXPECT_CALL(*mTimeStats,
1888 incrementJankyFrames(
1889 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001890 sLayerNameOne, sGameMode,
1891 JankType::PredictionError, -3, 5, 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08001892
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001893 addEmptyDisplayFrame();
1894
1895 // Fences for the second frame have flushed, so the present timestamps should be updated
1896 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1897 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1898 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1899 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1900
1901 actuals2 = presentedSurfaceFrame2.getActuals();
1902 EXPECT_EQ(actuals2.presentTime, 86);
1903 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1904 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1905 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1906}
1907
1908TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001909 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08001910
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001911 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001912 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001913 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -08001914 FrameTimelineInfo ftInfo;
1915 ftInfo.vsyncId = surfaceFrameToken1;
1916 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001917 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001918 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1919 sLayerNameOne, sLayerNameOne,
1920 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001921 surfaceFrame1->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001922 mFrameTimeline->setSfWakeUp(sfToken1, 42, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001923 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1924 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1925 mFrameTimeline->setSfPresent(46, presentFence1);
1926 auto displayFrame1 = getDisplayFrame(0);
1927 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1928 presentFence1->signalForTest(50);
1929
1930 // Fences for the first frame haven't been flushed yet, so it should be 0
1931 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1932 auto actuals1 = presentedSurfaceFrame1.getActuals();
1933 EXPECT_EQ(actuals1.presentTime, 0);
1934
1935 addEmptyDisplayFrame();
1936
1937 // Fences for the first frame have flushed, so the present timestamps should be updated
1938 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1939 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1940 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1941 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1942
1943 actuals1 = presentedSurfaceFrame1.getActuals();
1944 EXPECT_EQ(actuals1.presentTime, 50);
1945 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1946 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1947 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
1948}
1949
1950TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001951 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as only
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001952 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001953 // jank to the SurfaceFrame along with AppDeadlineMissed.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001954
Alec Mouri363faf02021-01-29 16:34:55 -08001955 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001956 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001957 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
1958 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001959 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1960 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
Huihong Luo3bdef862022-03-03 11:57:19 -08001961 FrameTimelineInfo ftInfo;
1962 ftInfo.vsyncId = surfaceFrameToken1;
1963 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001964 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001965 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1966 sLayerNameOne, sLayerNameOne,
1967 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001968 surfaceFrame1->setAcquireFenceTime(26);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001969 mFrameTimeline->setSfWakeUp(sfToken1, 32, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001970 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1971 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1972 mFrameTimeline->setSfPresent(36, presentFence1);
1973 auto displayFrame1 = getDisplayFrame(0);
1974 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1975 presentFence1->signalForTest(40);
1976
1977 // Fences for the first frame haven't been flushed yet, so it should be 0
1978 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1979 auto actuals1 = presentedSurfaceFrame1.getActuals();
1980 EXPECT_EQ(actuals1.presentTime, 0);
1981
1982 // Trigger a flush by finalizing the next DisplayFrame
1983 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08001984 FrameTimelineInfo ftInfo2;
1985 ftInfo2.vsyncId = surfaceFrameToken2;
1986 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001987 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001988 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1989 sLayerNameOne, sLayerNameOne,
1990 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001991 surfaceFrame2->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001992 mFrameTimeline->setSfWakeUp(sfToken2, 43, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001993 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1994 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1995 mFrameTimeline->setSfPresent(56, presentFence2);
1996 auto displayFrame2 = getDisplayFrame(1);
1997 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1998
1999 // Fences for the first frame have flushed, so the present timestamps should be updated
2000 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
2001 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2002 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2003 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2004
2005 actuals1 = presentedSurfaceFrame1.getActuals();
2006 EXPECT_EQ(actuals1.presentTime, 40);
2007 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2008 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2009 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2010
2011 // Fences for the second frame haven't been flushed yet, so it should be 0
2012 presentFence2->signalForTest(60);
2013 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2014 auto actuals2 = presentedSurfaceFrame2.getActuals();
2015 EXPECT_EQ(actuals2.presentTime, 0);
2016
2017 addEmptyDisplayFrame();
2018
2019 // Fences for the second frame have flushed, so the present timestamps should be updated
2020 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
2021 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2022 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2023 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
2024
2025 actuals2 = presentedSurfaceFrame2.getActuals();
2026 EXPECT_EQ(actuals2.presentTime, 60);
2027 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2028 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002029 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2030 JankType::SurfaceFlingerCpuDeadlineMissed | JankType::AppDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002031}
2032
2033TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002034 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08002035 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002036 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2037 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2038 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2039
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002040 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2041 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Huihong Luo3bdef862022-03-03 11:57:19 -08002042 FrameTimelineInfo ftInfo;
2043 ftInfo.vsyncId = surfaceFrameToken1;
2044 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002045 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002046 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2047 sLayerNameOne, sLayerNameOne,
2048 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002049 surfaceFrame1->setAcquireFenceTime(50);
Alec Mouri7d436ec2021-01-27 20:40:50 -08002050 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002051 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2052 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2053 mFrameTimeline->setSfPresent(56, presentFence1);
2054 auto displayFrame1 = getDisplayFrame(0);
2055 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2056 presentFence1->signalForTest(60);
2057
2058 // Fences for the first frame haven't been flushed yet, so it should be 0
2059 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2060 auto actuals1 = presentedSurfaceFrame1.getActuals();
2061 EXPECT_EQ(actuals1.presentTime, 0);
2062
2063 // Trigger a flush by finalizing the next DisplayFrame
2064 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002065 FrameTimelineInfo ftInfo2;
2066 ftInfo2.vsyncId = surfaceFrameToken2;
2067 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002068 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002069 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2070 sLayerNameOne, sLayerNameOne,
2071 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002072 surfaceFrame2->setAcquireFenceTime(84);
Alec Mouri7d436ec2021-01-27 20:40:50 -08002073 mFrameTimeline->setSfWakeUp(sfToken2, 112, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002074 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2075 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2076 mFrameTimeline->setSfPresent(116, presentFence2);
2077 auto displayFrame2 = getDisplayFrame(1);
2078 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2079 presentFence2->signalForTest(120);
2080
2081 // Fences for the first frame have flushed, so the present timestamps should be updated
2082 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2083 actuals1 = presentedSurfaceFrame1.getActuals();
2084 EXPECT_EQ(actuals1.endTime, 50);
2085 EXPECT_EQ(actuals1.presentTime, 60);
2086
2087 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2088 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2089 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2090
2091 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2092 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2093 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2094
2095 // Fences for the second frame haven't been flushed yet, so it should be 0
2096 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2097 auto actuals2 = presentedSurfaceFrame2.getActuals();
2098 EXPECT_EQ(actuals2.presentTime, 0);
2099
2100 addEmptyDisplayFrame();
2101
2102 // Fences for the second frame have flushed, so the present timestamps should be updated
2103 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
2104 actuals2 = presentedSurfaceFrame2.getActuals();
2105 EXPECT_EQ(actuals2.presentTime, 120);
2106
2107 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2108 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2109 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
2110
2111 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2112 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2113 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2114 JankType::AppDeadlineMissed | JankType::BufferStuffing);
2115}
Alec Mouriadebf5c2021-01-05 12:57:36 -08002116
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002117TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
2118 // Layer specific increment
2119 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
2120 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2121 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2122 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2123
2124 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2125 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -08002126 FrameTimelineInfo ftInfo;
2127 ftInfo.vsyncId = surfaceFrameToken1;
2128 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002129 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002130 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2131 sLayerNameOne, sLayerNameOne,
2132 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002133 surfaceFrame1->setAcquireFenceTime(50);
2134 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
2135 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2136 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2137 mFrameTimeline->setSfPresent(56, presentFence1);
2138 auto displayFrame1 = getDisplayFrame(0);
2139 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2140 presentFence1->signalForTest(60);
2141
2142 // Fences for the first frame haven't been flushed yet, so it should be 0
2143 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2144 auto actuals1 = presentedSurfaceFrame1.getActuals();
2145 EXPECT_EQ(actuals1.presentTime, 0);
2146
2147 // Trigger a flush by finalizing the next DisplayFrame
2148 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002149 FrameTimelineInfo ftInfo2;
2150 ftInfo2.vsyncId = surfaceFrameToken2;
2151 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002152 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002153 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2154 sLayerNameOne, sLayerNameOne,
2155 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002156 surfaceFrame2->setAcquireFenceTime(80);
2157 mFrameTimeline->setSfWakeUp(sfToken2, 82, Fps::fromPeriodNsecs(30));
2158 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
2159 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2160 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2161 mFrameTimeline->setSfPresent(86, presentFence2);
2162 auto displayFrame2 = getDisplayFrame(1);
2163 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2164 presentFence2->signalForTest(90);
2165
2166 // Fences for the first frame have flushed, so the present timestamps should be updated
2167 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2168 actuals1 = presentedSurfaceFrame1.getActuals();
2169 EXPECT_EQ(actuals1.endTime, 50);
2170 EXPECT_EQ(actuals1.presentTime, 60);
2171
2172 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2173 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2174 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2175
2176 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2177 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2178 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2179
2180 // Fences for the second frame haven't been flushed yet, so it should be 0
2181 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2182 auto actuals2 = presentedSurfaceFrame2.getActuals();
2183 EXPECT_EQ(actuals2.presentTime, 0);
2184
2185 addEmptyDisplayFrame();
2186
2187 // Fences for the second frame have flushed, so the present timestamps should be updated
2188 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2189 actuals2 = presentedSurfaceFrame2.getActuals();
2190 EXPECT_EQ(actuals2.presentTime, 90);
2191
2192 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2193 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2194 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
2195
2196 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2197 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2198 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
2199}
2200
Rachel Lee94917b32022-03-18 17:52:09 -07002201TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent_GpuAndCpuMiss) {
2202 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2203 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2204 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2205 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2206 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2207
2208 // Case 1: cpu time = 33 - 12 = 21, vsync period = 11
2209 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
2210 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
2211 auto displayFrame = getDisplayFrame(0);
2212 gpuFence1->signalForTest(36);
2213 presentFence1->signalForTest(52);
2214
2215 // Fences haven't been flushed yet, so it should be 0
2216 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
2217
2218 addEmptyDisplayFrame();
2219 displayFrame = getDisplayFrame(0);
2220
2221 // Fences have flushed, so the present timestamps should be updated
2222 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
2223 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2224 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2225 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
2226
2227 // Case 2: No GPU fence so it will not use GPU composition.
2228 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(30));
2229 mFrameTimeline->setSfPresent(66, presentFence2);
2230 auto displayFrame2 = getDisplayFrame(2); // 2 because of previous empty frame
2231 presentFence2->signalForTest(90);
2232
2233 // Fences for the frame haven't been flushed yet, so it should be 0
2234 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2235
2236 addEmptyDisplayFrame();
2237
2238 // Fences have flushed, so the present timestamps should be updated
2239 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2240 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2241 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2242 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
2243}
2244
Ady Abrahamfcb16862022-10-10 14:35:21 -07002245TEST_F(FrameTimelineTest, jankClassification_presentFenceError) {
2246 auto erroneousPresentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2247 auto erroneousPresentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2248 auto validPresentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2249 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
2250 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2251 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({72, 80, 80});
2252
2253 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
2254 mFrameTimeline->setSfPresent(26, erroneousPresentFence1);
2255
2256 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
2257 mFrameTimeline->setSfPresent(60, erroneousPresentFence2);
2258
2259 mFrameTimeline->setSfWakeUp(sfToken3, 72, Fps::fromPeriodNsecs(11));
2260 mFrameTimeline->setSfPresent(80, validPresentFence);
2261
2262 validPresentFence->signalForTest(80);
2263
2264 addEmptyDisplayFrame();
2265
2266 {
2267 auto displayFrame = getDisplayFrame(0);
2268 EXPECT_EQ(displayFrame->getActuals().presentTime, 26);
2269 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2270 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
2271 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
2272 }
2273 {
2274 auto displayFrame = getDisplayFrame(1);
2275 EXPECT_EQ(displayFrame->getActuals().presentTime, 60);
2276 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
2277 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
2278 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
2279 }
2280 {
2281 auto displayFrame = getDisplayFrame(2);
2282 EXPECT_EQ(displayFrame->getActuals().presentTime, 80);
2283 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2284 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2285 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
2286 }
2287}
2288
Alec Mouriadebf5c2021-01-05 12:57:36 -08002289TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
2290 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
2291}
2292
2293TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002294 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002295
2296 auto surfaceFrame1 =
2297 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002298 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002299 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002300 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2301 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2302 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2303 presentFence1->signalForTest(oneHundredMs);
2304 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2305
2306 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2307}
2308
2309TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002310 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2311 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002312 auto surfaceFrame1 =
2313 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002314 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002315 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002316 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2317 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2318 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2319 presentFence1->signalForTest(oneHundredMs);
2320 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2321
2322 auto surfaceFrame2 =
2323 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002324 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002325 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002326 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2327 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2328 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2329 presentFence2->signalForTest(twoHundredMs);
2330 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2331
2332 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
2333}
2334
2335TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002336 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2337 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002338 auto surfaceFrame1 =
2339 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002340 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002341 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002342 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2343 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2344 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2345 presentFence1->signalForTest(oneHundredMs);
2346 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2347
2348 auto surfaceFrame2 =
2349 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002350 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002351 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002352 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2353 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2354 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2355 presentFence2->signalForTest(twoHundredMs);
2356 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2357
2358 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
2359}
2360
2361TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002362 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2363 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002364 auto surfaceFrame1 =
2365 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002366 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002367 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002368 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2369 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2370 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2371 presentFence1->signalForTest(oneHundredMs);
2372 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2373
2374 auto surfaceFrame2 =
2375 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002376 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002377 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002378 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2379 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2380 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2381 presentFence2->signalForTest(twoHundredMs);
2382 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2383
2384 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2385}
2386
2387TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002388 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2389 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2390 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2391 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2392 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002393 auto surfaceFrame1 =
2394 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002395 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002396 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002397 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2398 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2399 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2400 presentFence1->signalForTest(oneHundredMs);
2401 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2402
2403 auto surfaceFrame2 =
2404 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002405 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002406 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002407 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2408 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2409 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2410 presentFence2->signalForTest(twoHundredMs);
2411 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2412
2413 auto surfaceFrame3 =
2414 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002415 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002416 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002417 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2418 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2419 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2420 presentFence3->signalForTest(threeHundredMs);
2421 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2422
2423 auto surfaceFrame4 =
2424 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002425 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002426 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002427 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2428 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2429 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2430 presentFence4->signalForTest(fiveHundredMs);
2431 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2432
2433 auto surfaceFrame5 =
2434 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002435 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002436 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002437 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2438 // Dropped frames will be excluded from fps computation
2439 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2440 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2441 presentFence5->signalForTest(sixHundredMs);
2442 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2443
2444 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2445}
2446
ramindaniea2bb822022-06-27 19:52:10 +00002447TEST_F(FrameTimelineTest, getMinTime) {
2448 // Use SurfaceFrame::getBaseTime to test the getMinTime.
2449 FrameTimelineInfo ftInfo;
2450
2451 // Valid prediction state test.
2452 ftInfo.vsyncId = 0L;
2453 mTokenManager->generateTokenForPredictions({10});
2454 auto surfaceFrame =
2455 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2456 sLayerNameOne, sLayerNameOne,
2457 /*isBuffer*/ true, sGameMode);
2458 ASSERT_EQ(surfaceFrame->getBaseTime(), 10);
2459
2460 // Test prediction state which is not valid.
2461 ftInfo.vsyncId = FrameTimelineInfo::INVALID_VSYNC_ID;
2462 surfaceFrame = mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2463 sLayerNameOne, sLayerNameOne,
2464 /*isBuffer*/ true, sGameMode);
2465 // Start time test.
2466 surfaceFrame->setActualStartTime(200);
2467 ASSERT_EQ(surfaceFrame->getBaseTime(), 200);
2468
2469 // End time test.
2470 surfaceFrame->setAcquireFenceTime(100);
2471 ASSERT_EQ(surfaceFrame->getBaseTime(), 100);
2472
2473 // Present time test.
2474 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2475 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
2476 mFrameTimeline->addSurfaceFrame(surfaceFrame);
2477 presentFence->signalForTest(std::chrono::nanoseconds(50ns).count());
2478 mFrameTimeline->setSfPresent(50, presentFence);
2479 ASSERT_EQ(surfaceFrame->getBaseTime(), 50);
2480}
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002481} // namespace android::frametimeline