blob: b3ab8f15d6bdd1f0a337e0d1f8cbee2399afef4b [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;
Alec Mouri9a29e672020-09-14 12:39:14 -070043
Adithya Srinivasanf279e042020-08-17 14:56:27 -070044namespace android::frametimeline {
45
46class FrameTimelineTest : public testing::Test {
47public:
48 FrameTimelineTest() {
49 const ::testing::TestInfo* const test_info =
50 ::testing::UnitTest::GetInstance()->current_test_info();
51 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
52 }
53
54 ~FrameTimelineTest() {
55 const ::testing::TestInfo* const test_info =
56 ::testing::UnitTest::GetInstance()->current_test_info();
57 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
58 }
59
Adithya Srinivasan01189672020-10-20 14:23:05 -070060 static void SetUpTestSuite() {
61 // Need to initialize tracing in process for testing, and only once per test suite.
62 perfetto::TracingInitArgs args;
63 args.backends = perfetto::kInProcessBackend;
64 perfetto::Tracing::Initialize(args);
65 }
66
Adithya Srinivasanf279e042020-08-17 14:56:27 -070067 void SetUp() override {
Alec Mouri9a29e672020-09-14 12:39:14 -070068 mTimeStats = std::make_shared<mock::TimeStats>();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000069 mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats, kSurfaceFlingerPid,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -080070 kTestThresholds);
Adithya Srinivasan01189672020-10-20 14:23:05 -070071 mFrameTimeline->registerDataSource();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070072 mTokenManager = &mFrameTimeline->mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000073 mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
Adithya Srinivasan2d736322020-10-01 16:53:48 -070074 maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070075 maxTokenRetentionTime = mTokenManager->kMaxRetentionTime;
76 }
77
Adithya Srinivasan01189672020-10-20 14:23:05 -070078 // Each tracing session can be used for a single block of Start -> Stop.
79 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
80 perfetto::TraceConfig cfg;
81 cfg.set_duration_ms(500);
82 cfg.add_buffers()->set_size_kb(1024);
83 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
84 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
85
86 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
87 tracingSession->Setup(cfg);
88 return tracingSession;
89 }
90
91 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
92 perfetto::TracingSession* tracingSession) {
93 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
94 perfetto::protos::Trace trace;
95 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
96
97 std::vector<perfetto::protos::TracePacket> packets;
98 for (const auto& packet : trace.packet()) {
99 if (!packet.has_frame_timeline_event()) {
100 continue;
101 }
102 packets.emplace_back(packet);
103 }
104 return packets;
105 }
106
107 void addEmptyDisplayFrame() {
108 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
109 mFrameTimeline->setSfPresent(2500, presentFence1);
110 }
111
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700112 void flushTokens(nsecs_t flushTime) {
113 std::lock_guard<std::mutex> lock(mTokenManager->mMutex);
114 mTokenManager->flushTokens(flushTime);
115 }
116
117 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
118 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800119 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
120 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700121 }
122
123 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
124 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
125 return mFrameTimeline->mDisplayFrames[idx];
126 }
127
128 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
129 return a.startTime == b.startTime && a.endTime == b.endTime &&
130 a.presentTime == b.presentTime;
131 }
132
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000133 const std::map<int64_t, TokenManagerPrediction>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700134 return mTokenManager->mPredictions;
135 }
136
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000137 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700138 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
139 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
140 }
141
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000142 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
143
144 void flushTrace() {
145 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
146 FrameTimelineDataSource::Trace(
147 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
148 }
149
Alec Mouri9a29e672020-09-14 12:39:14 -0700150 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700151 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
152 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000153 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700154 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700155 uint32_t* maxDisplayFrames;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700156 nsecs_t maxTokenRetentionTime;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000157 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800158 static constexpr nsecs_t kPresentThreshold =
159 std::chrono::duration_cast<std::chrono::nanoseconds>(2ns).count();
160 static constexpr nsecs_t kDeadlineThreshold =
161 std::chrono::duration_cast<std::chrono::nanoseconds>(2ns).count();
162 static constexpr nsecs_t kStartThreshold =
163 std::chrono::duration_cast<std::chrono::nanoseconds>(2ns).count();
164 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
165 kDeadlineThreshold,
166 kStartThreshold};
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700167};
168
Alec Mouri9a29e672020-09-14 12:39:14 -0700169static const std::string sLayerNameOne = "layer1";
170static const std::string sLayerNameTwo = "layer2";
171static constexpr const uid_t sUidOne = 0;
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700172static constexpr pid_t sPidOne = 10;
173static constexpr pid_t sPidTwo = 20;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000174static constexpr int32_t sInputEventId = 5;
Alec Mouri9a29e672020-09-14 12:39:14 -0700175
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700176TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
177 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000178 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700179 flushTokens(systemTime() + maxTokenRetentionTime);
180 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
181 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
182
183 // token1 should have expired
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000184 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700185 EXPECT_EQ(predictions.has_value(), false);
186
187 predictions = mTokenManager->getPredictionsForToken(token2);
188 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
189}
190
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700191TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000192 auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800193 sLayerNameOne, sLayerNameOne);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000194 auto surfaceFrame2 = mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800195 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700196 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
197 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
198}
199
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700200TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000201 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800202 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700203 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
204}
205
206TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
207 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
208 flushTokens(systemTime() + maxTokenRetentionTime);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000209 auto surfaceFrame =
210 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
211 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700212
213 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
214}
215
216TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
217 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000218 auto surfaceFrame =
219 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
220 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700221
222 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
223 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
224}
225
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000226TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
227 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
228 constexpr int32_t inputEventId = 1;
229 auto surfaceFrame =
230 mFrameTimeline->createSurfaceFrameForToken({token1, inputEventId}, sPidOne, sUidOne,
231 sLayerNameOne, sLayerNameOne);
232
233 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
234}
235
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700236TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800237 // Global increment
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700238 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
239 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
240
241 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
242 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000243 auto surfaceFrame1 =
244 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
245 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700246
247 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800248 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800249 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
250 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700251 mFrameTimeline->setSfPresent(25, presentFence1);
252 presentFence1->signalForTest(30);
253
254 // Trigger a flush by calling setSfPresent for the next frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800255 mFrameTimeline->setSfWakeUp(token2, 50, Fps::fromPeriodNsecs(11));
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700256 mFrameTimeline->setSfPresent(55, presentFence2);
257
258 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
259 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
260 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
261}
262
263TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800264 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800265 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700266 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
267 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
268 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
269 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
270 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 60});
Alec Mouri9a29e672020-09-14 12:39:14 -0700271 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000272 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
273 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700274 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000275 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
276 sUidOne, sLayerNameTwo, sLayerNameTwo);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800277 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800278 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
279 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
280 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
281 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700282 mFrameTimeline->setSfPresent(26, presentFence1);
283 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800284 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
285 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700286 presentFence1->signalForTest(42);
287
288 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800289 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700290 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
291 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
292
293 // Trigger a flush by finalizing the next DisplayFrame
294 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri9a29e672020-09-14 12:39:14 -0700295 auto surfaceFrame3 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000296 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
297 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800298 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800299 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Dropped);
300 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700301 mFrameTimeline->setSfPresent(56, presentFence2);
302 displayFrame = getDisplayFrame(0);
303
304 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800305 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700306 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
307 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100308 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
309 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700310}
311
312TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
313 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
314 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800315 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800316 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800317 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700318 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700319 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
320 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
321 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
322 int64_t sfToken = mTokenManager->generateTokenForPredictions(
323 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700324 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000325 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId},
326 sPidOne, sUidOne, sLayerNameOne,
327 sLayerNameOne);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800328 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800329 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
330 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700331 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
332 presentFence->signalForTest(32 + frameTimeFactor);
333 frameTimeFactor += 30;
334 }
335 auto displayFrame0 = getDisplayFrame(0);
336
337 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800338 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700339
340 // Add one more display frame
341 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
342 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
343 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
344 int64_t sfToken = mTokenManager->generateTokenForPredictions(
345 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700346 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000347 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
348 sUidOne, sLayerNameOne, sLayerNameOne);
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 displayFrame0 = getDisplayFrame(0);
355
356 // The window should have slided by 1 now and the previous 0th display frame
357 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800358 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700359}
360
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700361TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000362 auto surfaceFrame =
363 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, "acquireFenceAfterQueue",
364 "acquireFenceAfterQueue");
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700365 surfaceFrame->setActualQueueTime(123);
366 surfaceFrame->setAcquireFenceTime(456);
367 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
368}
369
370TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000371 auto surfaceFrame =
372 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, "acquireFenceAfterQueue",
373 "acquireFenceAfterQueue");
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700374 surfaceFrame->setActualQueueTime(456);
375 surfaceFrame->setAcquireFenceTime(123);
376 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
377}
378
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700379TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
380 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
381 presentFence->signalForTest(2);
382
383 // Size shouldn't exceed maxDisplayFrames - 64
384 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700385 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000386 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne,
387 sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700388 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800389 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800390 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
391 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700392 mFrameTimeline->setSfPresent(27, presentFence);
393 }
394 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
395
396 // Increase the size to 256
397 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000398 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700399
400 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700401 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000402 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne,
403 sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700404 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800405 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800406 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
407 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700408 mFrameTimeline->setSfPresent(27, presentFence);
409 }
410 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
411
412 // Shrink the size to 128
413 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000414 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700415
416 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700417 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000418 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne,
419 sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700420 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800421 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800422 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
423 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700424 mFrameTimeline->setSfPresent(27, presentFence);
425 }
426 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
427}
Alec Mouri9a29e672020-09-14 12:39:14 -0700428
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800429// Tests related to TimeStats
Alec Mouri9a29e672020-09-14 12:39:14 -0700430TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Alec Mouri363faf02021-01-29 16:34:55 -0800431 Fps refreshRate = Fps(11);
Alec Mouri9a29e672020-09-14 12:39:14 -0700432 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800433 incrementJankyFrames(
434 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
435 sLayerNameOne,
436 JankType::SurfaceFlingerCpuDeadlineMissed,
437 std::chrono::duration_cast<
438 std::chrono::nanoseconds>(3ms)
439 .count(),
440 std::chrono::duration_cast<
441 std::chrono::nanoseconds>(10ms)
442 .count(),
443 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700444 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
445 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
446 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
447 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
448 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
449 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
450 {std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
451 std::chrono::duration_cast<std::chrono::nanoseconds>(56ms).count(),
452 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
453 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000454 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
455 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700456 mFrameTimeline->setSfWakeUp(sfToken1,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800457 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
Alec Mouri363faf02021-01-29 16:34:55 -0800458 refreshRate);
459 surfaceFrame1->setAcquireFenceTime(
460 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count());
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800461 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
462 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700463 presentFence1->signalForTest(
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100464 std::chrono::duration_cast<std::chrono::nanoseconds>(70ms).count());
Alec Mouri9a29e672020-09-14 12:39:14 -0700465
466 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(59ms).count(),
467 presentFence1);
468}
469
470TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800471 Fps refreshRate = Fps::fromPeriodNsecs(30);
Alec Mouri9a29e672020-09-14 12:39:14 -0700472 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800473 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
474 sLayerNameOne, JankType::DisplayHAL,
475 0, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800476
Alec Mouri9a29e672020-09-14 12:39:14 -0700477 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
478 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
479 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
480 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
481 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
482 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
483 {std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
484 std::chrono::duration_cast<std::chrono::nanoseconds>(56ms).count(),
485 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
486 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000487 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
488 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700489 mFrameTimeline->setSfWakeUp(sfToken1,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800490 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
Alec Mouri363faf02021-01-29 16:34:55 -0800491 refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800492 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Alec Mouri363faf02021-01-29 16:34:55 -0800493 surfaceFrame1->setAcquireFenceTime(
494 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count());
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800495 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700496 presentFence1->signalForTest(
497 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count());
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800498 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(56ms).count(),
Alec Mouri9a29e672020-09-14 12:39:14 -0700499 presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800500 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700501}
502
503TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800504 Fps refreshRate = Fps(11.0);
Alec Mouri9a29e672020-09-14 12:39:14 -0700505 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800506 incrementJankyFrames(
507 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
508 sLayerNameOne, JankType::AppDeadlineMissed, 0, 0,
509 std::chrono::duration_cast<
510 std::chrono::nanoseconds>(25ms)
511 .count()}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700512 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
513 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
514 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
515 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
516 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
517 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800518 {std::chrono::duration_cast<std::chrono::nanoseconds>(82ms).count(),
519 std::chrono::duration_cast<std::chrono::nanoseconds>(86ms).count(),
520 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count()});
Alec Mouri9a29e672020-09-14 12:39:14 -0700521 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000522 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
523 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700524 surfaceFrame1->setAcquireFenceTime(
525 std::chrono::duration_cast<std::chrono::nanoseconds>(45ms).count());
526 mFrameTimeline->setSfWakeUp(sfToken1,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800527 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
Alec Mouri363faf02021-01-29 16:34:55 -0800528 refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700529
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800530 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
531 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700532 presentFence1->signalForTest(
533 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count());
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800534 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(86ms).count(),
Alec Mouri9a29e672020-09-14 12:39:14 -0700535 presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100536
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800537 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700538}
539
Alec Mouri363faf02021-01-29 16:34:55 -0800540TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
541 Fps refreshRate = Fps(11.0);
542 Fps renderRate = Fps(30.0);
543 EXPECT_CALL(*mTimeStats,
544 incrementJankyFrames(
545 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
546 JankType::AppDeadlineMissed, 0, 0,
547 std::chrono::duration_cast<
548 std::chrono::nanoseconds>(25ms)
549 .count()}));
550 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
551 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
552 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
553 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
554 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
555 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
556 {std::chrono::duration_cast<std::chrono::nanoseconds>(82ms).count(),
557 std::chrono::duration_cast<std::chrono::nanoseconds>(86ms).count(),
558 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count()});
559 auto surfaceFrame1 =
560 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
561 sUidOne, sLayerNameOne, sLayerNameOne);
562 surfaceFrame1->setAcquireFenceTime(
563 std::chrono::duration_cast<std::chrono::nanoseconds>(45ms).count());
564 mFrameTimeline->setSfWakeUp(sfToken1,
565 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
566 refreshRate);
567
568 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
569 surfaceFrame1->setRenderRate(renderRate);
570 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
571 presentFence1->signalForTest(
572 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count());
573 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(86ms).count(),
574 presentFence1);
575
576 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
577}
578
Adithya Srinivasan01189672020-10-20 14:23:05 -0700579/*
580 * Tracing Tests
581 *
582 * Trace packets are flushed all the way only when the next packet is traced.
583 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
584 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
585 * will have additional empty frames created for this reason.
586 */
587TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
588 auto tracingSession = getTracingSessionForTest();
589 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
590 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
591
592 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
593 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000594 auto surfaceFrame1 =
595 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
596 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700597
598 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800599 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800600 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
601 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700602 mFrameTimeline->setSfPresent(25, presentFence1);
603 presentFence1->signalForTest(30);
604
605 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
606 // next frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800607 mFrameTimeline->setSfWakeUp(token2, 50, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700608 mFrameTimeline->setSfPresent(55, presentFence2);
609
610 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000611 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700612}
613
614TEST_F(FrameTimelineTest, tracing_sanityTest) {
615 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800616 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800617 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700618 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
619 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
620
621 tracingSession->StartBlocking();
622 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
623 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000624 auto surfaceFrame1 =
625 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
626 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700627
628 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800629 mFrameTimeline->setSfWakeUp(token2, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800630 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
631 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700632 mFrameTimeline->setSfPresent(25, presentFence1);
633 presentFence1->signalForTest(30);
634
635 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
636 // next frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800637 mFrameTimeline->setSfWakeUp(token2, 50, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700638 mFrameTimeline->setSfPresent(55, presentFence2);
639 presentFence2->signalForTest(55);
640
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000641 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700642 tracingSession->StopBlocking();
643
644 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000645 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000646 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700647}
648
649TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
650 auto tracingSession = getTracingSessionForTest();
651 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
652 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
653
654 tracingSession->StartBlocking();
655 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
656
657 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800658 mFrameTimeline->setSfWakeUp(-1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700659 mFrameTimeline->setSfPresent(25, presentFence1);
660 presentFence1->signalForTest(30);
661
662 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
663 // next frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800664 mFrameTimeline->setSfWakeUp(token1, 50, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700665 mFrameTimeline->setSfPresent(55, presentFence2);
666 presentFence2->signalForTest(60);
667
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000668 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700669 tracingSession->StopBlocking();
670
671 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000672 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700673}
674
675TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
676 auto tracingSession = getTracingSessionForTest();
677 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
678 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
679
680 tracingSession->StartBlocking();
681 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
682 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000683 auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800684 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700685
686 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800687 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800688 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
689 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700690 mFrameTimeline->setSfPresent(25, presentFence1);
691 presentFence1->signalForTest(30);
692
693 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
694 // next frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800695 mFrameTimeline->setSfWakeUp(token2, 50, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700696 mFrameTimeline->setSfPresent(55, presentFence2);
697 presentFence2->signalForTest(60);
698
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000699 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700700 tracingSession->StopBlocking();
701
702 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000703 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
704 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000705 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700706}
707
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000708void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
709 const ProtoExpectedDisplayFrameStart& source) {
710 ASSERT_TRUE(received.has_cookie());
711 EXPECT_EQ(received.cookie(), source.cookie());
712
Adithya Srinivasan01189672020-10-20 14:23:05 -0700713 ASSERT_TRUE(received.has_token());
714 EXPECT_EQ(received.token(), source.token());
715
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000716 ASSERT_TRUE(received.has_pid());
717 EXPECT_EQ(received.pid(), source.pid());
718}
719
720void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
721 const ProtoActualDisplayFrameStart& source) {
722 ASSERT_TRUE(received.has_cookie());
723 EXPECT_EQ(received.cookie(), source.cookie());
724
725 ASSERT_TRUE(received.has_token());
726 EXPECT_EQ(received.token(), source.token());
727
728 ASSERT_TRUE(received.has_pid());
729 EXPECT_EQ(received.pid(), source.pid());
730
Adithya Srinivasan01189672020-10-20 14:23:05 -0700731 ASSERT_TRUE(received.has_present_type());
732 EXPECT_EQ(received.present_type(), source.present_type());
733 ASSERT_TRUE(received.has_on_time_finish());
734 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
735 ASSERT_TRUE(received.has_gpu_composition());
736 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
737 ASSERT_TRUE(received.has_jank_type());
738 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700739}
740
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000741void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
742 const ProtoExpectedSurfaceFrameStart& source) {
743 ASSERT_TRUE(received.has_cookie());
744 EXPECT_EQ(received.cookie(), source.cookie());
745
Adithya Srinivasan01189672020-10-20 14:23:05 -0700746 ASSERT_TRUE(received.has_token());
747 EXPECT_EQ(received.token(), source.token());
748
749 ASSERT_TRUE(received.has_display_frame_token());
750 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
751
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000752 ASSERT_TRUE(received.has_pid());
753 EXPECT_EQ(received.pid(), source.pid());
754
755 ASSERT_TRUE(received.has_layer_name());
756 EXPECT_EQ(received.layer_name(), source.layer_name());
757}
758
759void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
760 const ProtoActualSurfaceFrameStart& source) {
761 ASSERT_TRUE(received.has_cookie());
762 EXPECT_EQ(received.cookie(), source.cookie());
763
764 ASSERT_TRUE(received.has_token());
765 EXPECT_EQ(received.token(), source.token());
766
767 ASSERT_TRUE(received.has_display_frame_token());
768 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
769
770 ASSERT_TRUE(received.has_pid());
771 EXPECT_EQ(received.pid(), source.pid());
772
773 ASSERT_TRUE(received.has_layer_name());
774 EXPECT_EQ(received.layer_name(), source.layer_name());
775
Adithya Srinivasan01189672020-10-20 14:23:05 -0700776 ASSERT_TRUE(received.has_present_type());
777 EXPECT_EQ(received.present_type(), source.present_type());
778 ASSERT_TRUE(received.has_on_time_finish());
779 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
780 ASSERT_TRUE(received.has_gpu_composition());
781 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
782 ASSERT_TRUE(received.has_jank_type());
783 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000784}
Adithya Srinivasan01189672020-10-20 14:23:05 -0700785
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000786void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
787 ASSERT_TRUE(received.has_cookie());
788 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700789}
790
791TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
792 auto tracingSession = getTracingSessionForTest();
793 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
794 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
795
796 tracingSession->StartBlocking();
797 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
798 int64_t displayFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
799
800 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800801 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700802 mFrameTimeline->setSfPresent(26, presentFence1);
803 presentFence1->signalForTest(31);
804
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000805 int64_t traceCookie = snoopCurrentTraceCookie();
806 ProtoExpectedDisplayFrameStart protoExpectedDisplayFrameStart;
807 protoExpectedDisplayFrameStart.set_cookie(traceCookie + 1);
808 protoExpectedDisplayFrameStart.set_token(displayFrameToken1);
809 protoExpectedDisplayFrameStart.set_pid(kSurfaceFlingerPid);
810
811 ProtoFrameEnd protoExpectedDisplayFrameEnd;
812 protoExpectedDisplayFrameEnd.set_cookie(traceCookie + 1);
813
814 ProtoActualDisplayFrameStart protoActualDisplayFrameStart;
815 protoActualDisplayFrameStart.set_cookie(traceCookie + 2);
816 protoActualDisplayFrameStart.set_token(displayFrameToken1);
817 protoActualDisplayFrameStart.set_pid(kSurfaceFlingerPid);
818 protoActualDisplayFrameStart.set_present_type(
819 ProtoPresentType(FrameTimelineEvent::PRESENT_ON_TIME));
820 protoActualDisplayFrameStart.set_on_time_finish(true);
821 protoActualDisplayFrameStart.set_gpu_composition(false);
822 protoActualDisplayFrameStart.set_jank_type(ProtoJankType(FrameTimelineEvent::JANK_NONE));
823
824 ProtoFrameEnd protoActualDisplayFrameEnd;
825 protoActualDisplayFrameEnd.set_cookie(traceCookie + 2);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700826
827 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
828 // next frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800829 mFrameTimeline->setSfWakeUp(displayFrameToken2, 50, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700830 mFrameTimeline->setSfPresent(55, presentFence2);
831 presentFence2->signalForTest(55);
832
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000833 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700834 tracingSession->StopBlocking();
835
836 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000837 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700838
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000839 // Packet - 0 : ExpectedDisplayFrameStart
840 const auto& packet0 = packets[0];
841 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000842 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000843 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700844
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000845 const auto& event0 = packet0.frame_timeline_event();
846 ASSERT_TRUE(event0.has_expected_display_frame_start());
847 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
848 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
849
850 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
851 const auto& packet1 = packets[1];
852 ASSERT_TRUE(packet1.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000853 EXPECT_EQ(packet1.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000854 ASSERT_TRUE(packet1.has_frame_timeline_event());
855
856 const auto& event1 = packet1.frame_timeline_event();
857 ASSERT_TRUE(event1.has_frame_end());
858 const auto& expectedDisplayFrameEnd = event1.frame_end();
859 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
860
861 // Packet - 2 : ActualDisplayFrameStart
862 const auto& packet2 = packets[2];
863 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000864 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000865 ASSERT_TRUE(packet2.has_frame_timeline_event());
866
867 const auto& event2 = packet2.frame_timeline_event();
868 ASSERT_TRUE(event2.has_actual_display_frame_start());
869 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
870 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
871
872 // Packet - 3 : FrameEnd (ActualDisplayFrame)
873 const auto& packet3 = packets[3];
874 ASSERT_TRUE(packet3.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000875 EXPECT_EQ(packet3.timestamp(), 26u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000876 ASSERT_TRUE(packet3.has_frame_timeline_event());
877
878 const auto& event3 = packet3.frame_timeline_event();
879 ASSERT_TRUE(event3.has_frame_end());
880 const auto& actualDisplayFrameEnd = event3.frame_end();
881 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700882}
883
884TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
885 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800886 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800887 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700888 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
889 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
890
891 tracingSession->StartBlocking();
892 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
893 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
894 int64_t displayFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
895
896 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000897 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
898 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700899 surfaceFrame1->setActualStartTime(0);
900 surfaceFrame1->setActualQueueTime(15);
901 surfaceFrame1->setAcquireFenceTime(20);
902
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000903 // First 2 cookies will be used by the DisplayFrame
904 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
905
906 ProtoExpectedSurfaceFrameStart protoExpectedSurfaceFrameStart;
907 protoExpectedSurfaceFrameStart.set_cookie(traceCookie + 1);
908 protoExpectedSurfaceFrameStart.set_token(surfaceFrameToken);
909 protoExpectedSurfaceFrameStart.set_display_frame_token(displayFrameToken1);
910 protoExpectedSurfaceFrameStart.set_pid(sPidOne);
911 protoExpectedSurfaceFrameStart.set_layer_name(sLayerNameOne);
912
913 ProtoFrameEnd protoExpectedSurfaceFrameEnd;
914 protoExpectedSurfaceFrameEnd.set_cookie(traceCookie + 1);
915
916 ProtoActualSurfaceFrameStart protoActualSurfaceFrameStart;
917 protoActualSurfaceFrameStart.set_cookie(traceCookie + 2);
918 protoActualSurfaceFrameStart.set_token(surfaceFrameToken);
919 protoActualSurfaceFrameStart.set_display_frame_token(displayFrameToken1);
920 protoActualSurfaceFrameStart.set_pid(sPidOne);
921 protoActualSurfaceFrameStart.set_layer_name(sLayerNameOne);
922 protoActualSurfaceFrameStart.set_present_type(
923 ProtoPresentType(FrameTimelineEvent::PRESENT_ON_TIME));
924 protoActualSurfaceFrameStart.set_on_time_finish(true);
925 protoActualSurfaceFrameStart.set_gpu_composition(false);
926 protoActualSurfaceFrameStart.set_jank_type(ProtoJankType(FrameTimelineEvent::JANK_NONE));
927
928 ProtoFrameEnd protoActualSurfaceFrameEnd;
929 protoActualSurfaceFrameEnd.set_cookie(traceCookie + 2);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700930
931 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800932 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800933 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
934 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700935 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800936 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700937
938 // Trigger a flushPresentFence (which will call trace function) by calling setSfPresent for the
939 // next frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800940 mFrameTimeline->setSfWakeUp(displayFrameToken2, 50, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700941 mFrameTimeline->setSfPresent(55, presentFence2);
942 presentFence2->signalForTest(55);
943
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000944 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700945 tracingSession->StopBlocking();
946
947 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000948 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700949
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000950 // Packet - 4 : ExpectedSurfaceFrameStart
951 const auto& packet4 = packets[4];
952 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000953 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000954 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700955
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000956 const auto& event4 = packet4.frame_timeline_event();
957 ASSERT_TRUE(event4.has_expected_surface_frame_start());
958 const auto& expectedSurfaceFrameStart = event4.expected_surface_frame_start();
959 validateTraceEvent(expectedSurfaceFrameStart, protoExpectedSurfaceFrameStart);
960
961 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame)
962 const auto& packet5 = packets[5];
963 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000964 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000965 ASSERT_TRUE(packet5.has_frame_timeline_event());
966
967 const auto& event5 = packet5.frame_timeline_event();
968 ASSERT_TRUE(event5.has_frame_end());
969 const auto& expectedSurfaceFrameEnd = event5.frame_end();
970 validateTraceEvent(expectedSurfaceFrameEnd, protoExpectedSurfaceFrameEnd);
971
972 // Packet - 6 : ActualSurfaceFrameStart
973 const auto& packet6 = packets[6];
974 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000975 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000976 ASSERT_TRUE(packet6.has_frame_timeline_event());
977
978 const auto& event6 = packet6.frame_timeline_event();
979 ASSERT_TRUE(event6.has_actual_surface_frame_start());
980 const auto& actualSurfaceFrameStart = event6.actual_surface_frame_start();
981 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
982
983 // Packet - 7 : FrameEnd (ActualSurfaceFrame)
984 const auto& packet7 = packets[7];
985 ASSERT_TRUE(packet7.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000986 EXPECT_EQ(packet7.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000987 ASSERT_TRUE(packet7.has_frame_timeline_event());
988
989 const auto& event7 = packet7.frame_timeline_event();
990 ASSERT_TRUE(event7.has_frame_end());
991 const auto& actualSurfaceFrameEnd = event7.frame_end();
992 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700993}
994
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800995// Tests for Jank classification
996TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800997 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800998 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800999 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1000 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
1001 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
1002 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001003 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
1004 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001005 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001006 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1007 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1008 mFrameTimeline->setSfPresent(26, presentFence1);
1009 auto displayFrame = getDisplayFrame(0);
1010 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1011 presentFence1->signalForTest(29);
1012
1013 // Fences haven't been flushed yet, so it should be 0
1014 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1015 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1016
1017 addEmptyDisplayFrame();
1018 displayFrame = getDisplayFrame(0);
1019
1020 // Fences have flushed, so the present timestamps should be updated
1021 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1022 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1023 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1024 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1025 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
1026}
1027
1028TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001029 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001030 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1031 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1032 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001033 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001034 mFrameTimeline->setSfPresent(26, presentFence1);
1035 auto displayFrame = getDisplayFrame(0);
1036 presentFence1->signalForTest(30);
1037
1038 // Fences for the first frame haven't been flushed yet, so it should be 0
1039 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1040
1041 // Trigger a flush by finalizing the next DisplayFrame
1042 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001043 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001044 mFrameTimeline->setSfPresent(56, presentFence2);
1045 displayFrame = getDisplayFrame(0);
1046
1047 // Fences for the first frame have flushed, so the present timestamps should be updated
1048 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1049 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1050 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1051 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1052
1053 // Fences for the second frame haven't been flushed yet, so it should be 0
1054 auto displayFrame2 = getDisplayFrame(1);
1055 presentFence2->signalForTest(65);
1056 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001057 addEmptyDisplayFrame();
1058 displayFrame2 = getDisplayFrame(1);
1059
1060 // Fences for the second frame have flushed, so the present timestamps should be updated
1061 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1062 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1063 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1064 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1065}
1066
1067TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001068 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001069 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1070 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1071 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001072 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001073 mFrameTimeline->setSfPresent(26, presentFence1);
1074 auto displayFrame = getDisplayFrame(0);
1075 presentFence1->signalForTest(50);
1076
1077 // Fences for the first frame haven't been flushed yet, so it should be 0
1078 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1079
1080 // Trigger a flush by finalizing the next DisplayFrame
1081 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001082 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001083 mFrameTimeline->setSfPresent(56, presentFence2);
1084 displayFrame = getDisplayFrame(0);
1085
1086 // Fences for the first frame have flushed, so the present timestamps should be updated
1087 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1088 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1089 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1090 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1091
1092 // Fences for the second frame haven't been flushed yet, so it should be 0
1093 auto displayFrame2 = getDisplayFrame(1);
1094 presentFence2->signalForTest(75);
1095 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1096
1097 addEmptyDisplayFrame();
1098 displayFrame2 = getDisplayFrame(1);
1099
1100 // Fences for the second frame have flushed, so the present timestamps should be updated
1101 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1102 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1103 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1104 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1105}
1106
1107TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001108 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1109 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001110 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001111
1112 mFrameTimeline->setSfPresent(22, presentFence1);
1113 auto displayFrame = getDisplayFrame(0);
1114 presentFence1->signalForTest(28);
1115
1116 // Fences haven't been flushed yet, so it should be 0
1117 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1118
1119 addEmptyDisplayFrame();
1120 displayFrame = getDisplayFrame(0);
1121
1122 // Fences have flushed, so the present timestamps should be updated
1123 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1124 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1125 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1126 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1127}
1128
1129TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001130 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1131 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001132 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001133 mFrameTimeline->setSfPresent(36, presentFence1);
1134 auto displayFrame = getDisplayFrame(0);
1135 presentFence1->signalForTest(52);
1136
1137 // Fences haven't been flushed yet, so it should be 0
1138 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1139
1140 addEmptyDisplayFrame();
1141 displayFrame = getDisplayFrame(0);
1142
1143 // Fences have flushed, so the present timestamps should be updated
1144 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
1145 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1146 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1147 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1148}
1149
1150TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001151 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001152 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1153 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1154 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
1155 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1156 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1157 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001158 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1159 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001160 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001161 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001162 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1163 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1164 mFrameTimeline->setSfPresent(26, presentFence1);
1165 auto displayFrame1 = getDisplayFrame(0);
1166 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1167 presentFence1->signalForTest(30);
1168
1169 // Fences for the first frame haven't been flushed yet, so it should be 0
1170 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1171 auto actuals1 = presentedSurfaceFrame1.getActuals();
1172 EXPECT_EQ(actuals1.presentTime, 0);
1173
1174 // Trigger a flush by finalizing the next DisplayFrame
1175 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1176 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001177 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1178 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001179 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001180 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001181 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1182 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1183 mFrameTimeline->setSfPresent(56, presentFence2);
1184 auto displayFrame2 = getDisplayFrame(1);
1185 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1186
1187 // Fences for the first frame have flushed, so the present timestamps should be updated
1188 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1189 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1190 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1191 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1192
1193 actuals1 = presentedSurfaceFrame1.getActuals();
1194 EXPECT_EQ(actuals1.presentTime, 30);
1195 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1196 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1197 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1198
1199 // Fences for the second frame haven't been flushed yet, so it should be 0
1200 presentFence2->signalForTest(65);
1201 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1202 auto actuals2 = presentedSurfaceFrame2.getActuals();
1203 EXPECT_EQ(actuals2.presentTime, 0);
1204
Alec Mouri363faf02021-01-29 16:34:55 -08001205 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1206
1207 EXPECT_CALL(*mTimeStats,
1208 incrementJankyFrames(
1209 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
1210 sLayerNameOne, JankType::PredictionError, 0, 5,
1211 0}));
1212
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001213 addEmptyDisplayFrame();
1214
1215 // Fences for the second frame have flushed, so the present timestamps should be updated
1216 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1217 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1218 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1219 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1220
1221 actuals2 = presentedSurfaceFrame2.getActuals();
1222 EXPECT_EQ(actuals2.presentTime, 65);
1223 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1224 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1225 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1226}
1227
1228TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001229 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001230 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1231 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1232 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
1233 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1234 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1235 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001236 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1237 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001238 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001239 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001240 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1241 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1242 mFrameTimeline->setSfPresent(26, presentFence1);
1243 auto displayFrame1 = getDisplayFrame(0);
1244 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1245 presentFence1->signalForTest(50);
1246
1247 // Fences for the first frame haven't been flushed yet, so it should be 0
1248 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1249 auto actuals1 = presentedSurfaceFrame1.getActuals();
1250 EXPECT_EQ(actuals1.presentTime, 0);
1251
1252 // Trigger a flush by finalizing the next DisplayFrame
1253 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1254 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001255 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1256 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001257 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001258 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001259 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1260 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1261 mFrameTimeline->setSfPresent(56, presentFence2);
1262 auto displayFrame2 = getDisplayFrame(1);
1263 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1264
1265 // Fences for the first frame have flushed, so the present timestamps should be updated
1266 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1267 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1268 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1269 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1270
1271 actuals1 = presentedSurfaceFrame1.getActuals();
1272 EXPECT_EQ(actuals1.presentTime, 50);
1273 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1274 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1275 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1276
1277 // Fences for the second frame haven't been flushed yet, so it should be 0
1278 presentFence2->signalForTest(86);
1279 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1280 auto actuals2 = presentedSurfaceFrame2.getActuals();
1281 EXPECT_EQ(actuals2.presentTime, 0);
1282
Alec Mouri363faf02021-01-29 16:34:55 -08001283 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1284
1285 EXPECT_CALL(*mTimeStats,
1286 incrementJankyFrames(
1287 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
1288 sLayerNameOne, JankType::PredictionError, 0, 5,
1289 0}));
1290
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001291 addEmptyDisplayFrame();
1292
1293 // Fences for the second frame have flushed, so the present timestamps should be updated
1294 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1295 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1296 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1297 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1298
1299 actuals2 = presentedSurfaceFrame2.getActuals();
1300 EXPECT_EQ(actuals2.presentTime, 86);
1301 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1302 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1303 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1304}
1305
1306TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001307 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08001308
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001309 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1310 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 46, 50});
1311 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
1312 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001313 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1314 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001315 surfaceFrame1->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001316 mFrameTimeline->setSfWakeUp(sfToken1, 42, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001317 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1318 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1319 mFrameTimeline->setSfPresent(46, presentFence1);
1320 auto displayFrame1 = getDisplayFrame(0);
1321 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1322 presentFence1->signalForTest(50);
1323
1324 // Fences for the first frame haven't been flushed yet, so it should be 0
1325 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1326 auto actuals1 = presentedSurfaceFrame1.getActuals();
1327 EXPECT_EQ(actuals1.presentTime, 0);
1328
1329 addEmptyDisplayFrame();
1330
1331 // Fences for the first frame have flushed, so the present timestamps should be updated
1332 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1333 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1334 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1335 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1336
1337 actuals1 = presentedSurfaceFrame1.getActuals();
1338 EXPECT_EQ(actuals1.presentTime, 50);
1339 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1340 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1341 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
1342}
1343
1344TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
1345 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as
1346 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
1347 // jank to the SurfaceFrame.
1348
Alec Mouri363faf02021-01-29 16:34:55 -08001349 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001350 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1351 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 36, 40});
1352 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 46, 50});
1353 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1354 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
1355 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001356 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1357 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001358 surfaceFrame1->setAcquireFenceTime(26);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001359 mFrameTimeline->setSfWakeUp(sfToken1, 32, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001360 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1361 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1362 mFrameTimeline->setSfPresent(36, presentFence1);
1363 auto displayFrame1 = getDisplayFrame(0);
1364 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1365 presentFence1->signalForTest(40);
1366
1367 // Fences for the first frame haven't been flushed yet, so it should be 0
1368 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1369 auto actuals1 = presentedSurfaceFrame1.getActuals();
1370 EXPECT_EQ(actuals1.presentTime, 0);
1371
1372 // Trigger a flush by finalizing the next DisplayFrame
1373 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1374 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001375 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1376 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001377 surfaceFrame2->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001378 mFrameTimeline->setSfWakeUp(sfToken2, 43, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001379 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1380 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1381 mFrameTimeline->setSfPresent(56, presentFence2);
1382 auto displayFrame2 = getDisplayFrame(1);
1383 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1384
1385 // Fences for the first frame have flushed, so the present timestamps should be updated
1386 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
1387 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1388 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1389 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1390
1391 actuals1 = presentedSurfaceFrame1.getActuals();
1392 EXPECT_EQ(actuals1.presentTime, 40);
1393 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1394 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1395 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1396
1397 // Fences for the second frame haven't been flushed yet, so it should be 0
1398 presentFence2->signalForTest(60);
1399 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1400 auto actuals2 = presentedSurfaceFrame2.getActuals();
1401 EXPECT_EQ(actuals2.presentTime, 0);
1402
1403 addEmptyDisplayFrame();
1404
1405 // Fences for the second frame have flushed, so the present timestamps should be updated
1406 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
1407 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1408 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1409 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1410
1411 actuals2 = presentedSurfaceFrame2.getActuals();
1412 EXPECT_EQ(actuals2.presentTime, 60);
1413 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1414 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1415 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1416}
1417
1418TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001419 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001420 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001421 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1422 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
1423 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
1424
1425 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 56, 60});
1426 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 116, 120});
1427 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001428 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1429 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001430 surfaceFrame1->setAcquireFenceTime(50);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001431 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001432 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1433 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1434 mFrameTimeline->setSfPresent(56, presentFence1);
1435 auto displayFrame1 = getDisplayFrame(0);
1436 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1437 presentFence1->signalForTest(60);
1438
1439 // Fences for the first frame haven't been flushed yet, so it should be 0
1440 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1441 auto actuals1 = presentedSurfaceFrame1.getActuals();
1442 EXPECT_EQ(actuals1.presentTime, 0);
1443
1444 // Trigger a flush by finalizing the next DisplayFrame
1445 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1446 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001447 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1448 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001449 surfaceFrame2->setAcquireFenceTime(84);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001450 mFrameTimeline->setSfWakeUp(sfToken2, 112, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001451 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
1452 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1453 mFrameTimeline->setSfPresent(116, presentFence2);
1454 auto displayFrame2 = getDisplayFrame(1);
1455 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1456 presentFence2->signalForTest(120);
1457
1458 // Fences for the first frame have flushed, so the present timestamps should be updated
1459 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
1460 actuals1 = presentedSurfaceFrame1.getActuals();
1461 EXPECT_EQ(actuals1.endTime, 50);
1462 EXPECT_EQ(actuals1.presentTime, 60);
1463
1464 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1465 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1466 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1467
1468 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1469 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1470 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1471
1472 // Fences for the second frame haven't been flushed yet, so it should be 0
1473 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1474 auto actuals2 = presentedSurfaceFrame2.getActuals();
1475 EXPECT_EQ(actuals2.presentTime, 0);
1476
1477 addEmptyDisplayFrame();
1478
1479 // Fences for the second frame have flushed, so the present timestamps should be updated
1480 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1481 actuals2 = presentedSurfaceFrame2.getActuals();
1482 EXPECT_EQ(actuals2.presentTime, 120);
1483
1484 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1485 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1486 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
1487
1488 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1489 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1490 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
1491 JankType::AppDeadlineMissed | JankType::BufferStuffing);
1492}
Adithya Srinivasanf279e042020-08-17 14:56:27 -07001493} // namespace android::frametimeline