blob: bc379f2fb5a28736cb117035687143502582a5b3 [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
47class FrameTimelineTest : public testing::Test {
48public:
49 FrameTimelineTest() {
50 const ::testing::TestInfo* const test_info =
51 ::testing::UnitTest::GetInstance()->current_test_info();
52 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
53 }
54
55 ~FrameTimelineTest() {
56 const ::testing::TestInfo* const test_info =
57 ::testing::UnitTest::GetInstance()->current_test_info();
58 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
59 }
60
Adithya Srinivasan01189672020-10-20 14:23:05 -070061 static void SetUpTestSuite() {
62 // Need to initialize tracing in process for testing, and only once per test suite.
63 perfetto::TracingInitArgs args;
64 args.backends = perfetto::kInProcessBackend;
65 perfetto::Tracing::Initialize(args);
66 }
67
Adithya Srinivasanf279e042020-08-17 14:56:27 -070068 void SetUp() override {
Ady Abraham57f8e182022-03-08 15:54:33 -080069 constexpr bool kUseBootTimeClock = true;
Alec Mouri9a29e672020-09-14 12:39:14 -070070 mTimeStats = std::make_shared<mock::TimeStats>();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000071 mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats, kSurfaceFlingerPid,
Ady Abraham57f8e182022-03-08 15:54:33 -080072 kTestThresholds, !kUseBootTimeClock);
Adithya Srinivasan01189672020-10-20 14:23:05 -070073 mFrameTimeline->registerDataSource();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070074 mTokenManager = &mFrameTimeline->mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000075 mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
Adithya Srinivasan2d736322020-10-01 16:53:48 -070076 maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +000077 maxTokens = mTokenManager->kMaxTokens;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070078 }
79
Adithya Srinivasan01189672020-10-20 14:23:05 -070080 // Each tracing session can be used for a single block of Start -> Stop.
81 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
82 perfetto::TraceConfig cfg;
83 cfg.set_duration_ms(500);
84 cfg.add_buffers()->set_size_kb(1024);
85 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
86 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
87
88 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
89 tracingSession->Setup(cfg);
90 return tracingSession;
91 }
92
93 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
94 perfetto::TracingSession* tracingSession) {
95 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
96 perfetto::protos::Trace trace;
97 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
98
99 std::vector<perfetto::protos::TracePacket> packets;
100 for (const auto& packet : trace.packet()) {
101 if (!packet.has_frame_timeline_event()) {
102 continue;
103 }
104 packets.emplace_back(packet);
105 }
106 return packets;
107 }
108
109 void addEmptyDisplayFrame() {
110 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000111 // Trigger a flushPresentFence by calling setSfPresent for the next frame
Adithya Srinivasan01189672020-10-20 14:23:05 -0700112 mFrameTimeline->setSfPresent(2500, presentFence1);
113 }
114
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000115 void flushTokens() {
116 for (size_t i = 0; i < maxTokens; i++) {
117 mTokenManager->generateTokenForPredictions({});
118 }
119 EXPECT_EQ(getPredictions().size(), maxTokens);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700120 }
121
122 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
123 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800124 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
125 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700126 }
127
128 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
129 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
130 return mFrameTimeline->mDisplayFrames[idx];
131 }
132
133 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
134 return a.startTime == b.startTime && a.endTime == b.endTime &&
135 a.presentTime == b.presentTime;
136 }
137
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000138 const std::map<int64_t, TimelineItem>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700139 return mTokenManager->mPredictions;
140 }
141
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000142 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700143 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
144 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
145 }
146
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000147 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
148
149 void flushTrace() {
150 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
151 FrameTimelineDataSource::Trace(
152 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
153 }
154
Alec Mouri9a29e672020-09-14 12:39:14 -0700155 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700156 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
157 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000158 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700159 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700160 uint32_t* maxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000161 size_t maxTokens;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000162 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasanead17162021-02-18 02:17:37 +0000163 static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan54996e22021-06-25 22:26:45 +0000164 static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(0ns).count();
Adithya Srinivasanead17162021-02-18 02:17:37 +0000165 static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800166 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
167 kDeadlineThreshold,
168 kStartThreshold};
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700169};
170
Alec Mouri9a29e672020-09-14 12:39:14 -0700171static const std::string sLayerNameOne = "layer1";
172static const std::string sLayerNameTwo = "layer2";
Dominik Laskowskif5d0ea52021-09-26 17:27:01 -0700173
174constexpr const uid_t sUidOne = 0;
175constexpr pid_t sPidOne = 10;
176constexpr pid_t sPidTwo = 20;
177constexpr int32_t sInputEventId = 5;
178constexpr int32_t sLayerIdOne = 1;
179constexpr int32_t sLayerIdTwo = 2;
180constexpr GameMode sGameMode = GameMode::Unsupported;
Alec Mouri9a29e672020-09-14 12:39:14 -0700181
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700182TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
183 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000184 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000185 flushTokens();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700186 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
187 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
188
189 // token1 should have expired
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700190 EXPECT_EQ(predictions.has_value(), false);
191
192 predictions = mTokenManager->getPredictionsForToken(token2);
193 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
194}
195
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700196TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800197 auto surfaceFrame1 =
198 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000199 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000200 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -0800201 auto surfaceFrame2 =
202 mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000203 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000204 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700205 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
206 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
207}
208
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700209TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800210 auto surfaceFrame =
211 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000212 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000213 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700214 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
215}
216
217TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
218 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000219 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -0800220 FrameTimelineInfo ftInfo;
221 ftInfo.vsyncId = token1;
222 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000223 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800224 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
225 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000226 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700227
228 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
229}
230
231TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
232 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800233 FrameTimelineInfo ftInfo;
234 ftInfo.vsyncId = token1;
235 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000236 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800237 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
238 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000239 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700240
241 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
242 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
243}
244
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000245TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
246 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
247 constexpr int32_t inputEventId = 1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800248 FrameTimelineInfo ftInfo;
249 ftInfo.vsyncId = token1;
250 ftInfo.inputEventId = inputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000251 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800252 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
253 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000254 /*isBuffer*/ true, sGameMode);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000255
256 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
257}
258
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700259TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
260 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700261 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800262 FrameTimelineInfo ftInfo;
263 ftInfo.vsyncId = token1;
264 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000265 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800266 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
267 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000268 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700269
270 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800271 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000272 surfaceFrame1->setDropTime(12);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800273 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
274 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700275 mFrameTimeline->setSfPresent(25, presentFence1);
276 presentFence1->signalForTest(30);
277
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000278 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700279
280 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
281 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000282 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
283 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700284 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
285}
286
287TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800288 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800289 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700290 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
291 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700292 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800293 FrameTimelineInfo ftInfo;
294 ftInfo.vsyncId = surfaceFrameToken1;
295 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700296 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800297 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
298 sLayerNameOne, sLayerNameOne,
299 /*isBuffer*/ true, sGameMode);
Alec Mouri9a29e672020-09-14 12:39:14 -0700300 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800301 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdTwo,
302 sLayerNameTwo, sLayerNameTwo,
303 /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800304 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800305 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
306 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
307 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
308 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700309 mFrameTimeline->setSfPresent(26, presentFence1);
310 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800311 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
312 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700313 presentFence1->signalForTest(42);
314
315 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800316 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700317 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
318 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
319
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000320 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700321
322 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800323 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700324 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
325 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100326 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
327 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700328}
329
330TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
331 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
332 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800333 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800334 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800335 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700336 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700337 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
338 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
339 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
340 int64_t sfToken = mTokenManager->generateTokenForPredictions(
341 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800342 FrameTimelineInfo ftInfo;
343 ftInfo.vsyncId = surfaceFrameToken;
344 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700345 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800346 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000347 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000348 /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800349 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800350 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
351 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700352 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
353 presentFence->signalForTest(32 + frameTimeFactor);
354 frameTimeFactor += 30;
355 }
356 auto displayFrame0 = getDisplayFrame(0);
357
358 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800359 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700360
361 // Add one more display frame
362 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
363 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
364 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
365 int64_t sfToken = mTokenManager->generateTokenForPredictions(
366 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Huihong Luo3bdef862022-03-03 11:57:19 -0800367 FrameTimelineInfo ftInfo;
368 ftInfo.vsyncId = surfaceFrameToken;
369 ftInfo.inputEventId = sInputEventId;
Alec Mouri9a29e672020-09-14 12:39:14 -0700370 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -0800371 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
372 sLayerNameOne, sLayerNameOne,
373 /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800374 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800375 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
376 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700377 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
378 presentFence->signalForTest(32 + frameTimeFactor);
379 displayFrame0 = getDisplayFrame(0);
380
381 // The window should have slided by 1 now and the previous 0th display frame
382 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800383 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700384}
385
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700386TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000387 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
388 "acquireFenceAfterQueue",
389 "acquireFenceAfterQueue",
390 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700391 surfaceFrame->setActualQueueTime(123);
392 surfaceFrame->setAcquireFenceTime(456);
393 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
394}
395
396TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000397 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
398 "acquireFenceAfterQueue",
399 "acquireFenceAfterQueue",
400 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700401 surfaceFrame->setActualQueueTime(456);
402 surfaceFrame->setAcquireFenceTime(123);
403 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
404}
405
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700406TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
407 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
408 presentFence->signalForTest(2);
409
410 // Size shouldn't exceed maxDisplayFrames - 64
411 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700412 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800413 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000414 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000415 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700416 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800417 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800418 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
419 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700420 mFrameTimeline->setSfPresent(27, presentFence);
421 }
422 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
423
424 // Increase the size to 256
425 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000426 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700427
428 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700429 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800430 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000431 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000432 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700433 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800434 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800435 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
436 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700437 mFrameTimeline->setSfPresent(27, presentFence);
438 }
439 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
440
441 // Shrink the size to 128
442 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000443 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700444
445 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700446 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800447 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000448 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000449 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700450 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800451 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800452 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
453 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700454 mFrameTimeline->setSfPresent(27, presentFence);
455 }
456 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
457}
Alec Mouri9a29e672020-09-14 12:39:14 -0700458
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000459TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
460 Fps refreshRate = Fps::fromPeriodNsecs(11);
461
462 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
463 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
464 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800465 FrameTimelineInfo ftInfo;
466 ftInfo.vsyncId = surfaceFrameToken1;
467 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000468
469 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800470 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
471 sLayerNameOne, sLayerNameOne,
472 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000473 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
474 surfaceFrame1->setAcquireFenceTime(20);
475 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
476 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
477
478 mFrameTimeline->setSfPresent(59, presentFence1);
479 presentFence1->signalForTest(-1);
480 addEmptyDisplayFrame();
481
482 auto displayFrame0 = getDisplayFrame(0);
483 EXPECT_EQ(displayFrame0->getActuals().presentTime, -1);
484 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown);
485 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
486 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
487}
488
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800489// Tests related to TimeStats
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000490TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
491 Fps refreshRate = Fps::fromPeriodNsecs(11);
492 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
493 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
494 int64_t surfaceFrameToken1 = -1;
495 int64_t sfToken1 = -1;
Huihong Luo3bdef862022-03-03 11:57:19 -0800496 FrameTimelineInfo ftInfo;
497 ftInfo.vsyncId = surfaceFrameToken1;
498 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000499
500 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800501 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
502 sLayerNameOne, sLayerNameOne,
503 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000504 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
505 surfaceFrame1->setAcquireFenceTime(20);
506 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
507 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
508 presentFence1->signalForTest(70);
509
510 mFrameTimeline->setSfPresent(59, presentFence1);
511}
512
Alec Mouri9a29e672020-09-14 12:39:14 -0700513TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000514 Fps refreshRate = Fps::fromPeriodNsecs(11);
Alec Mouri9a29e672020-09-14 12:39:14 -0700515 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800516 incrementJankyFrames(
517 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000518 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000519 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800520 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700521 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000522 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
523 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800524 FrameTimelineInfo ftInfo;
525 ftInfo.vsyncId = surfaceFrameToken1;
526 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000527
Alec Mouri9a29e672020-09-14 12:39:14 -0700528 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800529 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
530 sLayerNameOne, sLayerNameOne,
531 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000532 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
533 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800534 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
535 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000536 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700537
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000538 mFrameTimeline->setSfPresent(62, presentFence1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700539}
540
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000541TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfGpu) {
542 Fps refreshRate = Fps::fromPeriodNsecs(11);
543 EXPECT_CALL(*mTimeStats,
544 incrementJankyFrames(
545 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000546 sLayerNameOne, sGameMode,
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000547 JankType::SurfaceFlingerGpuDeadlineMissed, 4, 10,
548 0}));
549 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
550 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
551 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
552 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800553 FrameTimelineInfo ftInfo;
554 ftInfo.vsyncId = surfaceFrameToken1;
555 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000556
557 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800558 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
559 sLayerNameOne, sLayerNameOne,
560 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000561 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
562 surfaceFrame1->setAcquireFenceTime(20);
563 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
564 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
565 gpuFence1->signalForTest(64);
566 presentFence1->signalForTest(70);
567
568 mFrameTimeline->setSfPresent(59, presentFence1, gpuFence1);
569}
570
Alec Mouri9a29e672020-09-14 12:39:14 -0700571TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800572 Fps refreshRate = Fps::fromPeriodNsecs(30);
Alec Mouri9a29e672020-09-14 12:39:14 -0700573 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800574 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000575 sLayerNameOne, sGameMode,
576 JankType::DisplayHAL, -4, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800577
Alec Mouri9a29e672020-09-14 12:39:14 -0700578 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000579 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
580 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800581 FrameTimelineInfo ftInfo;
582 ftInfo.vsyncId = surfaceFrameToken1;
583 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000584
Alec Mouri9a29e672020-09-14 12:39:14 -0700585 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800586 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
587 sLayerNameOne, sLayerNameOne,
588 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000589 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800590 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000591 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800592 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000593 presentFence1->signalForTest(90);
594 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800595 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700596}
597
598TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700599 Fps refreshRate = 11_Hz;
Alec Mouri9a29e672020-09-14 12:39:14 -0700600 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000601 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000602 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000603 JankType::AppDeadlineMissed, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000604 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700605 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000606 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
607 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800608 FrameTimelineInfo ftInfo;
609 ftInfo.vsyncId = surfaceFrameToken1;
610 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000611
Alec Mouri9a29e672020-09-14 12:39:14 -0700612 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800613 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
614 sLayerNameOne, sLayerNameOne,
615 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000616 surfaceFrame1->setAcquireFenceTime(45);
617 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700618
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800619 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
620 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000621 presentFence1->signalForTest(90);
622 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100623
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800624 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700625}
626
Adithya Srinivasanead17162021-02-18 02:17:37 +0000627TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000628 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000629 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000630 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000631 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000632 JankType::SurfaceFlingerScheduling,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000633 -4, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000634 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000635 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
636 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800637 FrameTimelineInfo ftInfo;
638 ftInfo.vsyncId = surfaceFrameToken1;
639 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000640
Adithya Srinivasanead17162021-02-18 02:17:37 +0000641 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800642 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
643 sLayerNameOne, sLayerNameOne,
644 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000645 surfaceFrame1->setAcquireFenceTime(50);
646 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000647
648 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
649 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000650 presentFence1->signalForTest(60);
651 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000652
653 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
654}
655
656TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000657 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000658 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000659 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000660 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000661 JankType::PredictionError, -4, 5,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000662 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000663 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000664 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
665 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800666 FrameTimelineInfo ftInfo;
667 ftInfo.vsyncId = surfaceFrameToken1;
668 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000669
Adithya Srinivasanead17162021-02-18 02:17:37 +0000670 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800671 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
672 sLayerNameOne, sLayerNameOne,
673 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000674 surfaceFrame1->setAcquireFenceTime(40);
675 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000676
677 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
678 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000679 presentFence1->signalForTest(65);
680 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000681
682 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
683}
684
685TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000686 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000687 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000688 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000689 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000690 JankType::BufferStuffing, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000691 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000692 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000693 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
694 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800695 FrameTimelineInfo ftInfo;
696 ftInfo.vsyncId = surfaceFrameToken1;
697 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000698
Adithya Srinivasanead17162021-02-18 02:17:37 +0000699 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800700 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
701 sLayerNameOne, sLayerNameOne,
702 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000703 surfaceFrame1->setAcquireFenceTime(40);
704 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000705
706 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000707 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000708 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000709 presentFence1->signalForTest(90);
710 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000711
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000712 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000713}
714
Alec Mouri363faf02021-01-29 16:34:55 -0800715TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000716 Fps refreshRate = Fps::fromPeriodNsecs(11);
717 Fps renderRate = Fps::fromPeriodNsecs(30);
Alec Mouri363faf02021-01-29 16:34:55 -0800718 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000719 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne,
720 sLayerNameOne, sGameMode,
721 JankType::AppDeadlineMissed, -4, 0,
722 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800723 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000724 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
725 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800726 FrameTimelineInfo ftInfo;
727 ftInfo.vsyncId = surfaceFrameToken1;
728 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000729
Alec Mouri363faf02021-01-29 16:34:55 -0800730 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800731 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
732 sLayerNameOne, sLayerNameOne,
733 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000734 surfaceFrame1->setAcquireFenceTime(45);
735 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800736
737 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
738 surfaceFrame1->setRenderRate(renderRate);
739 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000740 presentFence1->signalForTest(90);
741 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800742
743 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
744}
745
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000746TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
747 Fps refreshRate = Fps::fromPeriodNsecs(11);
748 Fps renderRate = Fps::fromPeriodNsecs(30);
749
750 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000751 incrementJankyFrames(
752 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000753 sGameMode,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000754 JankType::Unknown | JankType::AppDeadlineMissed,
Adithya Srinivasande272452021-04-10 00:21:00 +0000755 0, 0, 25}));
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000756 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
757 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
758 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -0800759 FrameTimelineInfo ftInfo;
760 ftInfo.vsyncId = surfaceFrameToken1;
761 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000762
763 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800764 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
765 sLayerNameOne, sLayerNameOne,
766 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000767 surfaceFrame1->setAcquireFenceTime(45);
768 // Trigger a prediction expiry
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000769 flushTokens();
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000770 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
771
772 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
773 surfaceFrame1->setRenderRate(renderRate);
774 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
775 presentFence1->signalForTest(90);
776 mFrameTimeline->setSfPresent(86, presentFence1);
777
778 auto displayFrame = getDisplayFrame(0);
779 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
780 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
781 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
782 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
783
784 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000785 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000786}
787
Adithya Srinivasan01189672020-10-20 14:23:05 -0700788/*
789 * Tracing Tests
790 *
791 * Trace packets are flushed all the way only when the next packet is traced.
792 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
793 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
794 * will have additional empty frames created for this reason.
795 */
796TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
797 auto tracingSession = getTracingSessionForTest();
798 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700799 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -0800800 FrameTimelineInfo ftInfo;
801 ftInfo.vsyncId = token1;
802 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000803 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800804 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
805 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000806 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700807
808 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800809 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800810 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
811 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700812 mFrameTimeline->setSfPresent(25, presentFence1);
813 presentFence1->signalForTest(30);
814
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000815 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700816
817 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000818 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700819}
820
821TEST_F(FrameTimelineTest, tracing_sanityTest) {
822 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800823 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800824 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700825 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700826
827 tracingSession->StartBlocking();
828 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
829 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -0800830 FrameTimelineInfo ftInfo;
831 ftInfo.vsyncId = token1;
832 ftInfo.inputEventId = sInputEventId;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000833 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -0800834 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
835 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000836 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700837
838 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800839 mFrameTimeline->setSfWakeUp(token2, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800840 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
841 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700842 mFrameTimeline->setSfPresent(25, presentFence1);
843 presentFence1->signalForTest(30);
844
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000845 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000846 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700847 tracingSession->StopBlocking();
848
849 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000850 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000851 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700852}
853
854TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
855 auto tracingSession = getTracingSessionForTest();
856 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700857
858 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700859
860 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800861 mFrameTimeline->setSfWakeUp(-1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700862 mFrameTimeline->setSfPresent(25, presentFence1);
863 presentFence1->signalForTest(30);
864
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000865 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000866 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700867 tracingSession->StopBlocking();
868
869 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000870 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700871}
872
873TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
874 auto tracingSession = getTracingSessionForTest();
875 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700876
877 tracingSession->StartBlocking();
878 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -0800879 auto surfaceFrame1 =
880 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000881 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000882 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700883
884 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800885 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800886 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
887 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700888 mFrameTimeline->setSfPresent(25, presentFence1);
889 presentFence1->signalForTest(30);
890
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000891 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000892 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700893 tracingSession->StopBlocking();
894
895 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000896 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
897 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000898 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700899}
900
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000901ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
902 pid_t pid) {
903 ProtoExpectedDisplayFrameStart proto;
904 proto.set_cookie(cookie);
905 proto.set_token(token);
906 proto.set_pid(pid);
907 return proto;
908}
909
910ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
911 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000912 bool gpuComposition, ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000913 ProtoActualDisplayFrameStart proto;
914 proto.set_cookie(cookie);
915 proto.set_token(token);
916 proto.set_pid(pid);
917 proto.set_present_type(presentType);
918 proto.set_on_time_finish(onTimeFinish);
919 proto.set_gpu_composition(gpuComposition);
920 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000921 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000922 return proto;
923}
924
925ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
926 int64_t displayFrameToken,
927 pid_t pid,
928 std::string layerName) {
929 ProtoExpectedSurfaceFrameStart proto;
930 proto.set_cookie(cookie);
931 proto.set_token(token);
932 proto.set_display_frame_token(displayFrameToken);
933 proto.set_pid(pid);
934 proto.set_layer_name(layerName);
935 return proto;
936}
937
938ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
939 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
940 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +0000941 ProtoJankType jankType, ProtoPredictionType predictionType, bool isBuffer) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000942 ProtoActualSurfaceFrameStart proto;
943 proto.set_cookie(cookie);
944 proto.set_token(token);
945 proto.set_display_frame_token(displayFrameToken);
946 proto.set_pid(pid);
947 proto.set_layer_name(layerName);
948 proto.set_present_type(presentType);
949 proto.set_on_time_finish(onTimeFinish);
950 proto.set_gpu_composition(gpuComposition);
951 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000952 proto.set_prediction_type(predictionType);
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +0000953 proto.set_is_buffer(isBuffer);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000954 return proto;
955}
956
957ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
958 ProtoFrameEnd proto;
959 proto.set_cookie(cookie);
960 return proto;
961}
962
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000963void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
964 const ProtoExpectedDisplayFrameStart& source) {
965 ASSERT_TRUE(received.has_cookie());
966 EXPECT_EQ(received.cookie(), source.cookie());
967
Adithya Srinivasan01189672020-10-20 14:23:05 -0700968 ASSERT_TRUE(received.has_token());
969 EXPECT_EQ(received.token(), source.token());
970
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000971 ASSERT_TRUE(received.has_pid());
972 EXPECT_EQ(received.pid(), source.pid());
973}
974
975void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
976 const ProtoActualDisplayFrameStart& source) {
977 ASSERT_TRUE(received.has_cookie());
978 EXPECT_EQ(received.cookie(), source.cookie());
979
980 ASSERT_TRUE(received.has_token());
981 EXPECT_EQ(received.token(), source.token());
982
983 ASSERT_TRUE(received.has_pid());
984 EXPECT_EQ(received.pid(), source.pid());
985
Adithya Srinivasan01189672020-10-20 14:23:05 -0700986 ASSERT_TRUE(received.has_present_type());
987 EXPECT_EQ(received.present_type(), source.present_type());
988 ASSERT_TRUE(received.has_on_time_finish());
989 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
990 ASSERT_TRUE(received.has_gpu_composition());
991 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
992 ASSERT_TRUE(received.has_jank_type());
993 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000994 ASSERT_TRUE(received.has_prediction_type());
995 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700996}
997
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000998void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
999 const ProtoExpectedSurfaceFrameStart& source) {
1000 ASSERT_TRUE(received.has_cookie());
1001 EXPECT_EQ(received.cookie(), source.cookie());
1002
Adithya Srinivasan01189672020-10-20 14:23:05 -07001003 ASSERT_TRUE(received.has_token());
1004 EXPECT_EQ(received.token(), source.token());
1005
1006 ASSERT_TRUE(received.has_display_frame_token());
1007 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1008
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001009 ASSERT_TRUE(received.has_pid());
1010 EXPECT_EQ(received.pid(), source.pid());
1011
1012 ASSERT_TRUE(received.has_layer_name());
1013 EXPECT_EQ(received.layer_name(), source.layer_name());
1014}
1015
1016void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
1017 const ProtoActualSurfaceFrameStart& source) {
1018 ASSERT_TRUE(received.has_cookie());
1019 EXPECT_EQ(received.cookie(), source.cookie());
1020
1021 ASSERT_TRUE(received.has_token());
1022 EXPECT_EQ(received.token(), source.token());
1023
1024 ASSERT_TRUE(received.has_display_frame_token());
1025 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
1026
1027 ASSERT_TRUE(received.has_pid());
1028 EXPECT_EQ(received.pid(), source.pid());
1029
1030 ASSERT_TRUE(received.has_layer_name());
1031 EXPECT_EQ(received.layer_name(), source.layer_name());
1032
Adithya Srinivasan01189672020-10-20 14:23:05 -07001033 ASSERT_TRUE(received.has_present_type());
1034 EXPECT_EQ(received.present_type(), source.present_type());
1035 ASSERT_TRUE(received.has_on_time_finish());
1036 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
1037 ASSERT_TRUE(received.has_gpu_composition());
1038 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
1039 ASSERT_TRUE(received.has_jank_type());
1040 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001041 ASSERT_TRUE(received.has_prediction_type());
1042 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001043 ASSERT_TRUE(received.has_is_buffer());
1044 EXPECT_EQ(received.is_buffer(), source.is_buffer());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001045}
Adithya Srinivasan01189672020-10-20 14:23:05 -07001046
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001047void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
1048 ASSERT_TRUE(received.has_cookie());
1049 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001050}
1051
1052TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
1053 auto tracingSession = getTracingSessionForTest();
1054 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001055
1056 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001057 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001058
1059 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -08001060 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -07001061 mFrameTimeline->setSfPresent(26, presentFence1);
1062 presentFence1->signalForTest(31);
1063
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001064 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001065 auto protoExpectedDisplayFrameStart =
1066 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1067 kSurfaceFlingerPid);
1068 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1069 auto protoActualDisplayFrameStart =
1070 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
1071 kSurfaceFlingerPid,
1072 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001073 FrameTimelineEvent::JANK_NONE,
1074 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001075 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001076
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001077 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001078 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001079 tracingSession->StopBlocking();
1080
1081 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001082 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001083
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001084 // Packet - 0 : ExpectedDisplayFrameStart
1085 const auto& packet0 = packets[0];
1086 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001087 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001088 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001089
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001090 const auto& event0 = packet0.frame_timeline_event();
1091 ASSERT_TRUE(event0.has_expected_display_frame_start());
1092 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
1093 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
1094
1095 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
1096 const auto& packet1 = packets[1];
1097 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001098 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001099 ASSERT_TRUE(packet1.has_frame_timeline_event());
1100
1101 const auto& event1 = packet1.frame_timeline_event();
1102 ASSERT_TRUE(event1.has_frame_end());
1103 const auto& expectedDisplayFrameEnd = event1.frame_end();
1104 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
1105
1106 // Packet - 2 : ActualDisplayFrameStart
1107 const auto& packet2 = packets[2];
1108 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001109 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001110 ASSERT_TRUE(packet2.has_frame_timeline_event());
1111
1112 const auto& event2 = packet2.frame_timeline_event();
1113 ASSERT_TRUE(event2.has_actual_display_frame_start());
1114 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1115 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1116
1117 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1118 const auto& packet3 = packets[3];
1119 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001120 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001121 ASSERT_TRUE(packet3.has_frame_timeline_event());
1122
1123 const auto& event3 = packet3.frame_timeline_event();
1124 ASSERT_TRUE(event3.has_frame_end());
1125 const auto& actualDisplayFrameEnd = event3.frame_end();
1126 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001127}
1128
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001129TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1130 auto tracingSession = getTracingSessionForTest();
1131 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1132
1133 tracingSession->StartBlocking();
1134 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1135 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001136 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001137
1138 // Set up the display frame
1139 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
1140 mFrameTimeline->setSfPresent(26, presentFence1);
1141 presentFence1->signalForTest(31);
1142
1143 int64_t traceCookie = snoopCurrentTraceCookie();
1144
1145 auto protoActualDisplayFrameStart =
1146 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1147 kSurfaceFlingerPid,
1148 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001149 false, FrameTimelineEvent::JANK_UNKNOWN,
1150 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001151 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1152
1153 addEmptyDisplayFrame();
1154 flushTrace();
1155 tracingSession->StopBlocking();
1156
1157 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1158 // Only actual timeline packets should be in the trace
1159 EXPECT_EQ(packets.size(), 2u);
1160
1161 // Packet - 0 : ActualDisplayFrameStart
1162 const auto& packet0 = packets[0];
1163 ASSERT_TRUE(packet0.has_timestamp());
1164 EXPECT_EQ(packet0.timestamp(), 20u);
1165 ASSERT_TRUE(packet0.has_frame_timeline_event());
1166
1167 const auto& event0 = packet0.frame_timeline_event();
1168 ASSERT_TRUE(event0.has_actual_display_frame_start());
1169 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1170 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1171
1172 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1173 const auto& packet1 = packets[1];
1174 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001175 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001176 ASSERT_TRUE(packet1.has_frame_timeline_event());
1177
1178 const auto& event1 = packet1.frame_timeline_event();
1179 ASSERT_TRUE(event1.has_frame_end());
1180 const auto& actualDisplayFrameEnd = event1.frame_end();
1181 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1182}
1183
Adithya Srinivasan01189672020-10-20 14:23:05 -07001184TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1185 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001186 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001187 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -07001188 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1189 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1190
1191 tracingSession->StartBlocking();
1192 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1193 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001194
Huihong Luo3bdef862022-03-03 11:57:19 -08001195 FrameTimelineInfo ftInfo;
1196 ftInfo.vsyncId = surfaceFrameToken;
1197 ftInfo.inputEventId = sInputEventId;
1198
Adithya Srinivasan01189672020-10-20 14:23:05 -07001199 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001200 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1201 sLayerNameOne, sLayerNameOne,
1202 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001203 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001204 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1205 sLayerNameOne, sLayerNameOne,
1206 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001207 surfaceFrame1->setActualQueueTime(10);
1208 surfaceFrame1->setDropTime(15);
1209
1210 surfaceFrame2->setActualQueueTime(15);
1211 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001212
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001213 // First 2 cookies will be used by the DisplayFrame
1214 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1215
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001216 auto protoDroppedSurfaceFrameExpectedStart =
1217 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1218 displayFrameToken1, sPidOne, sLayerNameOne);
1219 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1220 auto protoDroppedSurfaceFrameActualStart =
1221 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1222 displayFrameToken1, sPidOne, sLayerNameOne,
1223 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001224 FrameTimelineEvent::JANK_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001225 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001226 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001227
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001228 auto protoPresentedSurfaceFrameExpectedStart =
1229 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1230 displayFrameToken1, sPidOne, sLayerNameOne);
1231 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1232 auto protoPresentedSurfaceFrameActualStart =
1233 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1234 displayFrameToken1, sPidOne, sLayerNameOne,
1235 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001236 FrameTimelineEvent::JANK_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001237 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001238 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001239
1240 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -08001241 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001242 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1243 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001244 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001245 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001246 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001247 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001248
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001249 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001250 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001251 tracingSession->StopBlocking();
1252
1253 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001254 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1255 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001256
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001257 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001258 const auto& packet4 = packets[4];
1259 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001260 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001261 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001262
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001263 const auto& event4 = packet4.frame_timeline_event();
1264 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001265 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1266 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001267
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001268 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001269 const auto& packet5 = packets[5];
1270 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001271 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001272 ASSERT_TRUE(packet5.has_frame_timeline_event());
1273
1274 const auto& event5 = packet5.frame_timeline_event();
1275 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001276 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1277 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001278
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001279 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001280 const auto& packet6 = packets[6];
1281 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001282 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001283 ASSERT_TRUE(packet6.has_frame_timeline_event());
1284
1285 const auto& event6 = packet6.frame_timeline_event();
1286 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001287 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1288 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001289
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001290 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001291 const auto& packet7 = packets[7];
1292 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001293 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001294 ASSERT_TRUE(packet7.has_frame_timeline_event());
1295
1296 const auto& event7 = packet7.frame_timeline_event();
1297 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001298 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1299 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1300
1301 // Packet - 8 : ExpectedSurfaceFrameStart2
1302 const auto& packet8 = packets[8];
1303 ASSERT_TRUE(packet8.has_timestamp());
1304 EXPECT_EQ(packet8.timestamp(), 10u);
1305 ASSERT_TRUE(packet8.has_frame_timeline_event());
1306
1307 const auto& event8 = packet8.frame_timeline_event();
1308 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1309 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1310 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1311
1312 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1313 const auto& packet9 = packets[9];
1314 ASSERT_TRUE(packet9.has_timestamp());
1315 EXPECT_EQ(packet9.timestamp(), 25u);
1316 ASSERT_TRUE(packet9.has_frame_timeline_event());
1317
1318 const auto& event9 = packet9.frame_timeline_event();
1319 ASSERT_TRUE(event9.has_frame_end());
1320 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1321 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1322
1323 // Packet - 10 : ActualSurfaceFrameStart2
1324 const auto& packet10 = packets[10];
1325 ASSERT_TRUE(packet10.has_timestamp());
1326 EXPECT_EQ(packet10.timestamp(), 10u);
1327 ASSERT_TRUE(packet10.has_frame_timeline_event());
1328
1329 const auto& event10 = packet10.frame_timeline_event();
1330 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1331 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1332 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1333
1334 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1335 const auto& packet11 = packets[11];
1336 ASSERT_TRUE(packet11.has_timestamp());
1337 EXPECT_EQ(packet11.timestamp(), 20u);
1338 ASSERT_TRUE(packet11.has_frame_timeline_event());
1339
1340 const auto& event11 = packet11.frame_timeline_event();
1341 ASSERT_TRUE(event11.has_frame_end());
1342 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1343 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1344}
1345
Ady Abrahame43ff722022-02-15 14:44:25 -08001346TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredIsAppMissedDeadline) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001347 auto tracingSession = getTracingSessionForTest();
1348 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1349
1350 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001351 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1352 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1353 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001354 int64_t surfaceFrameToken =
1355 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1356
1357 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001358 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001359 FrameTimelineInfo ftInfo;
1360 ftInfo.vsyncId = surfaceFrameToken;
1361 ftInfo.inputEventId = 0;
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001362 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001363 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1364 sLayerNameOne, sLayerNameOne,
1365 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001366 surfaceFrame1->setActualQueueTime(appEndTime);
1367 surfaceFrame1->setAcquireFenceTime(appEndTime);
1368
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001369 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1370 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1371 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001372 int64_t displayFrameToken =
1373 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1374
1375 // First 2 cookies will be used by the DisplayFrame
1376 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1377
1378 auto protoActualSurfaceFrameStart =
1379 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1380 displayFrameToken, sPidOne, sLayerNameOne,
1381 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Ady Abrahame43ff722022-02-15 14:44:25 -08001382 false, FrameTimelineEvent::JANK_APP_DEADLINE_MISSED,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001383 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001384 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1385
1386 // Set up the display frame
1387 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1388 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1389 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1390 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1391 presentFence1->signalForTest(sfPresentTime);
1392
1393 addEmptyDisplayFrame();
1394 flushTrace();
1395 tracingSession->StopBlocking();
1396
1397 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1398 // Display Frame 4 packets + SurfaceFrame 2 packets
1399 ASSERT_EQ(packets.size(), 6u);
1400
1401 // Packet - 4 : ActualSurfaceFrameStart
1402 const auto& packet4 = packets[4];
1403 ASSERT_TRUE(packet4.has_timestamp());
1404 EXPECT_EQ(packet4.timestamp(),
1405 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1406 ASSERT_TRUE(packet4.has_frame_timeline_event());
1407
1408 const auto& event4 = packet4.frame_timeline_event();
1409 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1410 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1411 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1412
1413 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1414 const auto& packet5 = packets[5];
1415 ASSERT_TRUE(packet5.has_timestamp());
1416 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1417 ASSERT_TRUE(packet5.has_frame_timeline_event());
1418
1419 const auto& event5 = packet5.frame_timeline_event();
1420 ASSERT_TRUE(event5.has_frame_end());
1421 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001422 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001423}
1424
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001425TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDroppedFramesTracedProperly) {
1426 auto tracingSession = getTracingSessionForTest();
1427 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1428
1429 tracingSession->StartBlocking();
1430 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1431 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1432 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
1433 int64_t surfaceFrameToken =
1434 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1435
1436 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001437 flushTokens();
Huihong Luo3bdef862022-03-03 11:57:19 -08001438 FrameTimelineInfo ftInfo;
1439 ftInfo.vsyncId = surfaceFrameToken;
1440 ftInfo.inputEventId = 0;
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001441 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001442 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1443 sLayerNameOne, sLayerNameOne,
1444 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001445
1446 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(22ms).count();
1447 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1448 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
1449 int64_t displayFrameToken =
1450 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1451
1452 // First 2 cookies will be used by the DisplayFrame
1453 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1454
1455 auto protoActualSurfaceFrameStart =
1456 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1457 displayFrameToken, sPidOne, sLayerNameOne,
1458 FrameTimelineEvent::PRESENT_DROPPED, false, false,
1459 FrameTimelineEvent::JANK_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001460 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001461 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1462
1463 // Set up the display frame
1464 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1465 surfaceFrame1->setDropTime(sfStartTime);
1466 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1467 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1468 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1469 presentFence1->signalForTest(sfPresentTime);
1470
1471 addEmptyDisplayFrame();
1472 flushTrace();
1473 tracingSession->StopBlocking();
1474
1475 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1476 // Display Frame 4 packets + SurfaceFrame 2 packets
1477 ASSERT_EQ(packets.size(), 6u);
1478
1479 // Packet - 4 : ActualSurfaceFrameStart
1480 const auto& packet4 = packets[4];
1481 ASSERT_TRUE(packet4.has_timestamp());
1482 EXPECT_EQ(packet4.timestamp(),
1483 static_cast<uint64_t>(sfStartTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1484 ASSERT_TRUE(packet4.has_frame_timeline_event());
1485
1486 const auto& event4 = packet4.frame_timeline_event();
1487 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1488 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1489 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1490
1491 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1492 const auto& packet5 = packets[5];
1493 ASSERT_TRUE(packet5.has_timestamp());
1494 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(sfStartTime));
1495 ASSERT_TRUE(packet5.has_frame_timeline_event());
1496
1497 const auto& event5 = packet5.frame_timeline_event();
1498 ASSERT_TRUE(event5.has_frame_end());
1499 const auto& actualSurfaceFrameEnd = event5.frame_end();
1500 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
1501}
1502
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001503// Tests for Jank classification
1504TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001505 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001506 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001507 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1508 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001509 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Huihong Luo3bdef862022-03-03 11:57:19 -08001510 FrameTimelineInfo ftInfo;
1511 ftInfo.vsyncId = surfaceFrameToken;
1512 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001513 auto surfaceFrame =
Huihong Luo3bdef862022-03-03 11:57:19 -08001514 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1515 sLayerNameOne, sLayerNameOne,
1516 /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001517 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001518 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1519 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1520 mFrameTimeline->setSfPresent(26, presentFence1);
1521 auto displayFrame = getDisplayFrame(0);
1522 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1523 presentFence1->signalForTest(29);
1524
1525 // Fences haven't been flushed yet, so it should be 0
1526 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1527 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1528
1529 addEmptyDisplayFrame();
1530 displayFrame = getDisplayFrame(0);
1531
1532 // Fences have flushed, so the present timestamps should be updated
1533 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1534 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1535 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1536 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1537 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
1538}
1539
1540TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001541 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001542 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001543 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1544 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001545 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001546 mFrameTimeline->setSfPresent(26, presentFence1);
1547 auto displayFrame = getDisplayFrame(0);
1548 presentFence1->signalForTest(30);
1549
1550 // Fences for the first frame haven't been flushed yet, so it should be 0
1551 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1552
1553 // Trigger a flush by finalizing the next DisplayFrame
1554 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001555 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001556 mFrameTimeline->setSfPresent(56, presentFence2);
1557 displayFrame = getDisplayFrame(0);
1558
1559 // Fences for the first frame have flushed, so the present timestamps should be updated
1560 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1561 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1562 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1563 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1564
1565 // Fences for the second frame haven't been flushed yet, so it should be 0
1566 auto displayFrame2 = getDisplayFrame(1);
1567 presentFence2->signalForTest(65);
1568 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001569 addEmptyDisplayFrame();
1570 displayFrame2 = getDisplayFrame(1);
1571
1572 // Fences for the second frame have flushed, so the present timestamps should be updated
1573 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1574 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1575 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1576 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1577}
1578
1579TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001580 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001581 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001582 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1583 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001584 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001585 mFrameTimeline->setSfPresent(26, presentFence1);
1586 auto displayFrame = getDisplayFrame(0);
1587 presentFence1->signalForTest(50);
1588
1589 // Fences for the first frame haven't been flushed yet, so it should be 0
1590 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1591
1592 // Trigger a flush by finalizing the next DisplayFrame
1593 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001594 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001595 mFrameTimeline->setSfPresent(56, presentFence2);
1596 displayFrame = getDisplayFrame(0);
1597
1598 // Fences for the first frame have flushed, so the present timestamps should be updated
1599 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1600 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1601 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1602 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1603
1604 // Fences for the second frame haven't been flushed yet, so it should be 0
1605 auto displayFrame2 = getDisplayFrame(1);
1606 presentFence2->signalForTest(75);
1607 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1608
1609 addEmptyDisplayFrame();
1610 displayFrame2 = getDisplayFrame(1);
1611
1612 // Fences for the second frame have flushed, so the present timestamps should be updated
1613 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1614 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1615 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1616 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1617}
1618
1619TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001620 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1621 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001622 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001623
1624 mFrameTimeline->setSfPresent(22, presentFence1);
1625 auto displayFrame = getDisplayFrame(0);
1626 presentFence1->signalForTest(28);
1627
1628 // Fences haven't been flushed yet, so it should be 0
1629 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1630
1631 addEmptyDisplayFrame();
1632 displayFrame = getDisplayFrame(0);
1633
1634 // Fences have flushed, so the present timestamps should be updated
1635 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1636 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1637 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1638 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1639}
1640
1641TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001642 /*
1643 * Case 1 - cpu time > vsync period but combined time > deadline > deadline -> cpudeadlinemissed
1644 * Case 2 - cpu time < vsync period but combined time > deadline -> gpudeadlinemissed
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001645 * Case 3 - previous frame ran longer -> sf_stuffing
1646 * Case 4 - Long cpu under SF stuffing -> cpudeadlinemissed
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001647 */
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001648 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001649 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001650 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1651 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001652 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1653 auto gpuFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001654 auto gpuFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1655 auto gpuFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001656 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001657 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001658 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1659 int64_t sfToken4 = mTokenManager->generateTokenForPredictions({112, 120, 120});
1660
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001661 // case 1 - cpu time = 33 - 12 = 21, vsync period = 11
Alec Mouri7d436ec2021-01-27 20:40:50 -08001662 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001663 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
1664 auto displayFrame0 = getDisplayFrame(0);
1665 gpuFence1->signalForTest(36);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001666 presentFence1->signalForTest(52);
1667
1668 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001669 EXPECT_EQ(displayFrame0->getActuals().presentTime, 0);
1670
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001671 // case 2 - cpu time = 56 - 52 = 4, vsync period = 30
1672 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001673 mFrameTimeline->setSfPresent(56, presentFence2, gpuFence2);
1674 auto displayFrame1 = getDisplayFrame(1);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001675 gpuFence2->signalForTest(76);
1676 presentFence2->signalForTest(90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001677
1678 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1679 // Fences have flushed for first displayFrame, so the present timestamps should be updated
1680 EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
1681 EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1682 EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1683 EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001684
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001685 // case 3 - cpu time = 86 - 82 = 4, vsync period = 30
1686 mFrameTimeline->setSfWakeUp(sfToken3, 106, Fps::fromPeriodNsecs(30));
1687 mFrameTimeline->setSfPresent(112, presentFence3, gpuFence3);
1688 auto displayFrame2 = getDisplayFrame(2);
1689 gpuFence3->signalForTest(116);
1690 presentFence3->signalForTest(120);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001691
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001692 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001693 // Fences have flushed for second displayFrame, so the present timestamps should be updated
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001694 EXPECT_EQ(displayFrame1->getActuals().presentTime, 90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001695 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1696 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1697 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001698
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001699 // case 4 - cpu time = 86 - 82 = 4, vsync period = 30
1700 mFrameTimeline->setSfWakeUp(sfToken4, 120, Fps::fromPeriodNsecs(30));
1701 mFrameTimeline->setSfPresent(140, presentFence4, gpuFence4);
1702 auto displayFrame3 = getDisplayFrame(3);
1703 gpuFence4->signalForTest(156);
1704 presentFence4->signalForTest(180);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001705
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001706 EXPECT_EQ(displayFrame3->getActuals().presentTime, 0);
1707 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1708 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1709 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1710 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1711 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerStuffing);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001712
1713 addEmptyDisplayFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001714
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001715 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1716 EXPECT_EQ(displayFrame3->getActuals().presentTime, 180);
1717 EXPECT_EQ(displayFrame3->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1718 EXPECT_EQ(displayFrame3->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1719 EXPECT_EQ(displayFrame3->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001720}
1721
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001722TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001723 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001724 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001725 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1726 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001727 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1728 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08001729 FrameTimelineInfo ftInfo;
1730 ftInfo.vsyncId = surfaceFrameToken1;
1731 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001732 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001733 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1734 sLayerNameOne, sLayerNameOne,
1735 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001736 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001737 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001738 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1739 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001740 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001741 auto displayFrame1 = getDisplayFrame(0);
1742 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1743 presentFence1->signalForTest(30);
1744
1745 // Fences for the first frame haven't been flushed yet, so it should be 0
1746 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1747 auto actuals1 = presentedSurfaceFrame1.getActuals();
1748 EXPECT_EQ(actuals1.presentTime, 0);
1749
1750 // Trigger a flush by finalizing the next DisplayFrame
1751 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08001752 FrameTimelineInfo ftInfo2;
1753 ftInfo2.vsyncId = surfaceFrameToken2;
1754 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001755 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001756 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1757 sLayerNameOne, sLayerNameOne,
1758 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001759 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001760 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001761 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1762 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001763 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001764 auto displayFrame2 = getDisplayFrame(1);
1765 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1766
1767 // Fences for the first frame have flushed, so the present timestamps should be updated
1768 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1769 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1770 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1771 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1772
1773 actuals1 = presentedSurfaceFrame1.getActuals();
1774 EXPECT_EQ(actuals1.presentTime, 30);
1775 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1776 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1777 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1778
1779 // Fences for the second frame haven't been flushed yet, so it should be 0
1780 presentFence2->signalForTest(65);
1781 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1782 auto actuals2 = presentedSurfaceFrame2.getActuals();
1783 EXPECT_EQ(actuals2.presentTime, 0);
1784
Alec Mouri363faf02021-01-29 16:34:55 -08001785 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1786
1787 EXPECT_CALL(*mTimeStats,
1788 incrementJankyFrames(
1789 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001790 sLayerNameOne, sGameMode,
1791 JankType::PredictionError, -3, 5, 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08001792
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001793 addEmptyDisplayFrame();
1794
1795 // Fences for the second frame have flushed, so the present timestamps should be updated
1796 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1797 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1798 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1799 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1800
1801 actuals2 = presentedSurfaceFrame2.getActuals();
1802 EXPECT_EQ(actuals2.presentTime, 65);
1803 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1804 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1805 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1806}
1807
1808TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001809 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001810 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001811 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1812 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001813 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1814 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
Huihong Luo3bdef862022-03-03 11:57:19 -08001815 FrameTimelineInfo ftInfo;
1816 ftInfo.vsyncId = surfaceFrameToken1;
1817 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001818 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001819 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1820 sLayerNameOne, sLayerNameOne,
1821 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001822 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001823 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001824 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1825 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1826 mFrameTimeline->setSfPresent(26, presentFence1);
1827 auto displayFrame1 = getDisplayFrame(0);
1828 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1829 presentFence1->signalForTest(50);
1830
1831 // Fences for the first frame haven't been flushed yet, so it should be 0
1832 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1833 auto actuals1 = presentedSurfaceFrame1.getActuals();
1834 EXPECT_EQ(actuals1.presentTime, 0);
1835
1836 // Trigger a flush by finalizing the next DisplayFrame
1837 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08001838 FrameTimelineInfo ftInfo2;
1839 ftInfo2.vsyncId = surfaceFrameToken2;
1840 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001841 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001842 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1843 sLayerNameOne, sLayerNameOne,
1844 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001845 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001846 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001847 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1848 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001849 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001850 auto displayFrame2 = getDisplayFrame(1);
1851 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1852
1853 // Fences for the first frame have flushed, so the present timestamps should be updated
1854 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1855 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1856 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1857 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1858
1859 actuals1 = presentedSurfaceFrame1.getActuals();
1860 EXPECT_EQ(actuals1.presentTime, 50);
1861 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1862 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1863 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1864
1865 // Fences for the second frame haven't been flushed yet, so it should be 0
1866 presentFence2->signalForTest(86);
1867 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1868 auto actuals2 = presentedSurfaceFrame2.getActuals();
1869 EXPECT_EQ(actuals2.presentTime, 0);
1870
Alec Mouri363faf02021-01-29 16:34:55 -08001871 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1872
1873 EXPECT_CALL(*mTimeStats,
1874 incrementJankyFrames(
1875 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001876 sLayerNameOne, sGameMode,
1877 JankType::PredictionError, -3, 5, 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08001878
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001879 addEmptyDisplayFrame();
1880
1881 // Fences for the second frame have flushed, so the present timestamps should be updated
1882 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1883 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1884 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1885 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1886
1887 actuals2 = presentedSurfaceFrame2.getActuals();
1888 EXPECT_EQ(actuals2.presentTime, 86);
1889 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1890 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1891 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1892}
1893
1894TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001895 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08001896
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001897 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001898 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001899 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
Huihong Luo3bdef862022-03-03 11:57:19 -08001900 FrameTimelineInfo ftInfo;
1901 ftInfo.vsyncId = surfaceFrameToken1;
1902 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001903 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001904 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1905 sLayerNameOne, sLayerNameOne,
1906 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001907 surfaceFrame1->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001908 mFrameTimeline->setSfWakeUp(sfToken1, 42, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001909 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1910 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1911 mFrameTimeline->setSfPresent(46, presentFence1);
1912 auto displayFrame1 = getDisplayFrame(0);
1913 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1914 presentFence1->signalForTest(50);
1915
1916 // Fences for the first frame haven't been flushed yet, so it should be 0
1917 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1918 auto actuals1 = presentedSurfaceFrame1.getActuals();
1919 EXPECT_EQ(actuals1.presentTime, 0);
1920
1921 addEmptyDisplayFrame();
1922
1923 // Fences for the first frame have flushed, so the present timestamps should be updated
1924 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1925 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1926 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1927 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1928
1929 actuals1 = presentedSurfaceFrame1.getActuals();
1930 EXPECT_EQ(actuals1.presentTime, 50);
1931 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1932 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1933 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
1934}
1935
1936TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001937 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as only
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001938 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001939 // jank to the SurfaceFrame along with AppDeadlineMissed.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001940
Alec Mouri363faf02021-01-29 16:34:55 -08001941 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001942 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001943 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
1944 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001945 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1946 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
Huihong Luo3bdef862022-03-03 11:57:19 -08001947 FrameTimelineInfo ftInfo;
1948 ftInfo.vsyncId = surfaceFrameToken1;
1949 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001950 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001951 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
1952 sLayerNameOne, sLayerNameOne,
1953 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001954 surfaceFrame1->setAcquireFenceTime(26);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001955 mFrameTimeline->setSfWakeUp(sfToken1, 32, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001956 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1957 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1958 mFrameTimeline->setSfPresent(36, presentFence1);
1959 auto displayFrame1 = getDisplayFrame(0);
1960 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1961 presentFence1->signalForTest(40);
1962
1963 // Fences for the first frame haven't been flushed yet, so it should be 0
1964 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1965 auto actuals1 = presentedSurfaceFrame1.getActuals();
1966 EXPECT_EQ(actuals1.presentTime, 0);
1967
1968 // Trigger a flush by finalizing the next DisplayFrame
1969 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08001970 FrameTimelineInfo ftInfo2;
1971 ftInfo2.vsyncId = surfaceFrameToken2;
1972 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001973 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08001974 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
1975 sLayerNameOne, sLayerNameOne,
1976 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001977 surfaceFrame2->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001978 mFrameTimeline->setSfWakeUp(sfToken2, 43, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001979 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1980 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1981 mFrameTimeline->setSfPresent(56, presentFence2);
1982 auto displayFrame2 = getDisplayFrame(1);
1983 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1984
1985 // Fences for the first frame have flushed, so the present timestamps should be updated
1986 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
1987 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1988 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1989 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1990
1991 actuals1 = presentedSurfaceFrame1.getActuals();
1992 EXPECT_EQ(actuals1.presentTime, 40);
1993 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1994 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1995 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1996
1997 // Fences for the second frame haven't been flushed yet, so it should be 0
1998 presentFence2->signalForTest(60);
1999 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2000 auto actuals2 = presentedSurfaceFrame2.getActuals();
2001 EXPECT_EQ(actuals2.presentTime, 0);
2002
2003 addEmptyDisplayFrame();
2004
2005 // Fences for the second frame have flushed, so the present timestamps should be updated
2006 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
2007 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2008 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2009 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
2010
2011 actuals2 = presentedSurfaceFrame2.getActuals();
2012 EXPECT_EQ(actuals2.presentTime, 60);
2013 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2014 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Adithya Srinivasan8a945502021-03-19 19:12:32 +00002015 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2016 JankType::SurfaceFlingerCpuDeadlineMissed | JankType::AppDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002017}
2018
2019TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002020 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08002021 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002022 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2023 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2024 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2025
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002026 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2027 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Huihong Luo3bdef862022-03-03 11:57:19 -08002028 FrameTimelineInfo ftInfo;
2029 ftInfo.vsyncId = surfaceFrameToken1;
2030 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002031 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002032 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2033 sLayerNameOne, sLayerNameOne,
2034 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002035 surfaceFrame1->setAcquireFenceTime(50);
Alec Mouri7d436ec2021-01-27 20:40:50 -08002036 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002037 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2038 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2039 mFrameTimeline->setSfPresent(56, presentFence1);
2040 auto displayFrame1 = getDisplayFrame(0);
2041 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2042 presentFence1->signalForTest(60);
2043
2044 // Fences for the first frame haven't been flushed yet, so it should be 0
2045 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2046 auto actuals1 = presentedSurfaceFrame1.getActuals();
2047 EXPECT_EQ(actuals1.presentTime, 0);
2048
2049 // Trigger a flush by finalizing the next DisplayFrame
2050 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002051 FrameTimelineInfo ftInfo2;
2052 ftInfo2.vsyncId = surfaceFrameToken2;
2053 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002054 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002055 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2056 sLayerNameOne, sLayerNameOne,
2057 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002058 surfaceFrame2->setAcquireFenceTime(84);
Alec Mouri7d436ec2021-01-27 20:40:50 -08002059 mFrameTimeline->setSfWakeUp(sfToken2, 112, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08002060 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2061 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2062 mFrameTimeline->setSfPresent(116, presentFence2);
2063 auto displayFrame2 = getDisplayFrame(1);
2064 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2065 presentFence2->signalForTest(120);
2066
2067 // Fences for the first frame have flushed, so the present timestamps should be updated
2068 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2069 actuals1 = presentedSurfaceFrame1.getActuals();
2070 EXPECT_EQ(actuals1.endTime, 50);
2071 EXPECT_EQ(actuals1.presentTime, 60);
2072
2073 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2074 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2075 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2076
2077 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2078 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2079 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2080
2081 // Fences for the second frame haven't been flushed yet, so it should be 0
2082 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2083 auto actuals2 = presentedSurfaceFrame2.getActuals();
2084 EXPECT_EQ(actuals2.presentTime, 0);
2085
2086 addEmptyDisplayFrame();
2087
2088 // Fences for the second frame have flushed, so the present timestamps should be updated
2089 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
2090 actuals2 = presentedSurfaceFrame2.getActuals();
2091 EXPECT_EQ(actuals2.presentTime, 120);
2092
2093 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2094 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2095 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
2096
2097 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2098 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2099 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2100 JankType::AppDeadlineMissed | JankType::BufferStuffing);
2101}
Alec Mouriadebf5c2021-01-05 12:57:36 -08002102
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002103TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
2104 // Layer specific increment
2105 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
2106 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2107 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2108 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2109
2110 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2111 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
Huihong Luo3bdef862022-03-03 11:57:19 -08002112 FrameTimelineInfo ftInfo;
2113 ftInfo.vsyncId = surfaceFrameToken1;
2114 ftInfo.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002115 auto surfaceFrame1 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002116 mFrameTimeline->createSurfaceFrameForToken(ftInfo, sPidOne, sUidOne, sLayerIdOne,
2117 sLayerNameOne, sLayerNameOne,
2118 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002119 surfaceFrame1->setAcquireFenceTime(50);
2120 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
2121 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2122 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2123 mFrameTimeline->setSfPresent(56, presentFence1);
2124 auto displayFrame1 = getDisplayFrame(0);
2125 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2126 presentFence1->signalForTest(60);
2127
2128 // Fences for the first frame haven't been flushed yet, so it should be 0
2129 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2130 auto actuals1 = presentedSurfaceFrame1.getActuals();
2131 EXPECT_EQ(actuals1.presentTime, 0);
2132
2133 // Trigger a flush by finalizing the next DisplayFrame
2134 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Huihong Luo3bdef862022-03-03 11:57:19 -08002135 FrameTimelineInfo ftInfo2;
2136 ftInfo2.vsyncId = surfaceFrameToken2;
2137 ftInfo2.inputEventId = sInputEventId;
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002138 auto surfaceFrame2 =
Huihong Luo3bdef862022-03-03 11:57:19 -08002139 mFrameTimeline->createSurfaceFrameForToken(ftInfo2, sPidOne, sUidOne, sLayerIdOne,
2140 sLayerNameOne, sLayerNameOne,
2141 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002142 surfaceFrame2->setAcquireFenceTime(80);
2143 mFrameTimeline->setSfWakeUp(sfToken2, 82, Fps::fromPeriodNsecs(30));
2144 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
2145 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2146 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2147 mFrameTimeline->setSfPresent(86, presentFence2);
2148 auto displayFrame2 = getDisplayFrame(1);
2149 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2150 presentFence2->signalForTest(90);
2151
2152 // Fences for the first frame have flushed, so the present timestamps should be updated
2153 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2154 actuals1 = presentedSurfaceFrame1.getActuals();
2155 EXPECT_EQ(actuals1.endTime, 50);
2156 EXPECT_EQ(actuals1.presentTime, 60);
2157
2158 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2159 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2160 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2161
2162 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2163 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2164 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2165
2166 // Fences for the second frame haven't been flushed yet, so it should be 0
2167 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2168 auto actuals2 = presentedSurfaceFrame2.getActuals();
2169 EXPECT_EQ(actuals2.presentTime, 0);
2170
2171 addEmptyDisplayFrame();
2172
2173 // Fences for the second frame have flushed, so the present timestamps should be updated
2174 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2175 actuals2 = presentedSurfaceFrame2.getActuals();
2176 EXPECT_EQ(actuals2.presentTime, 90);
2177
2178 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2179 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2180 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
2181
2182 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2183 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2184 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
2185}
2186
Alec Mouriadebf5c2021-01-05 12:57:36 -08002187TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
2188 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
2189}
2190
2191TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002192 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002193
2194 auto surfaceFrame1 =
2195 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002196 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002197 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002198 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2199 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2200 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2201 presentFence1->signalForTest(oneHundredMs);
2202 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2203
2204 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2205}
2206
2207TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002208 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2209 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002210 auto surfaceFrame1 =
2211 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002212 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002213 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002214 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2215 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2216 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2217 presentFence1->signalForTest(oneHundredMs);
2218 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2219
2220 auto surfaceFrame2 =
2221 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002222 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002223 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002224 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2225 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2226 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2227 presentFence2->signalForTest(twoHundredMs);
2228 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2229
2230 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
2231}
2232
2233TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002234 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2235 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002236 auto surfaceFrame1 =
2237 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002238 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002239 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002240 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2241 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2242 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2243 presentFence1->signalForTest(oneHundredMs);
2244 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2245
2246 auto surfaceFrame2 =
2247 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002248 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002249 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002250 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2251 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2252 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2253 presentFence2->signalForTest(twoHundredMs);
2254 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2255
2256 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
2257}
2258
2259TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002260 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2261 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002262 auto surfaceFrame1 =
2263 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002264 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002265 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002266 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2267 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2268 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2269 presentFence1->signalForTest(oneHundredMs);
2270 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2271
2272 auto surfaceFrame2 =
2273 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002274 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002275 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002276 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2277 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2278 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2279 presentFence2->signalForTest(twoHundredMs);
2280 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2281
2282 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2283}
2284
2285TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002286 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2287 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2288 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2289 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2290 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002291 auto surfaceFrame1 =
2292 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002293 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002294 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002295 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2296 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2297 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2298 presentFence1->signalForTest(oneHundredMs);
2299 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2300
2301 auto surfaceFrame2 =
2302 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002303 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002304 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002305 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2306 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2307 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2308 presentFence2->signalForTest(twoHundredMs);
2309 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2310
2311 auto surfaceFrame3 =
2312 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002313 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002314 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002315 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2316 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2317 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2318 presentFence3->signalForTest(threeHundredMs);
2319 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2320
2321 auto surfaceFrame4 =
2322 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002323 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002324 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002325 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2326 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2327 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2328 presentFence4->signalForTest(fiveHundredMs);
2329 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2330
2331 auto surfaceFrame5 =
2332 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002333 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002334 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002335 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2336 // Dropped frames will be excluded from fps computation
2337 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2338 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2339 presentFence5->signalForTest(sixHundredMs);
2340 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2341
2342 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2343}
2344
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002345} // namespace android::frametimeline