blob: 1c57e4c7335ebf166346a5cf679ddcdbc4cd0d47 [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);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000109 // Trigger a flushPresentFence by calling setSfPresent for the next frame
Adithya Srinivasan01189672020-10-20 14:23:05 -0700110 mFrameTimeline->setSfPresent(2500, presentFence1);
111 }
112
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700113 void flushTokens(nsecs_t flushTime) {
114 std::lock_guard<std::mutex> lock(mTokenManager->mMutex);
115 mTokenManager->flushTokens(flushTime);
116 }
117
118 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
119 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800120 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
121 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700122 }
123
124 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
125 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
126 return mFrameTimeline->mDisplayFrames[idx];
127 }
128
129 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
130 return a.startTime == b.startTime && a.endTime == b.endTime &&
131 a.presentTime == b.presentTime;
132 }
133
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000134 const std::map<int64_t, TokenManagerPrediction>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700135 return mTokenManager->mPredictions;
136 }
137
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000138 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700139 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
140 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
141 }
142
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000143 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
144
145 void flushTrace() {
146 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
147 FrameTimelineDataSource::Trace(
148 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
149 }
150
Alec Mouri9a29e672020-09-14 12:39:14 -0700151 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700152 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
153 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000154 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700155 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700156 uint32_t* maxDisplayFrames;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700157 nsecs_t maxTokenRetentionTime;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000158 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800159 static constexpr nsecs_t kPresentThreshold =
160 std::chrono::duration_cast<std::chrono::nanoseconds>(2ns).count();
161 static constexpr nsecs_t kDeadlineThreshold =
162 std::chrono::duration_cast<std::chrono::nanoseconds>(2ns).count();
163 static constexpr nsecs_t kStartThreshold =
164 std::chrono::duration_cast<std::chrono::nanoseconds>(2ns).count();
165 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
166 kDeadlineThreshold,
167 kStartThreshold};
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700168};
169
Alec Mouri9a29e672020-09-14 12:39:14 -0700170static const std::string sLayerNameOne = "layer1";
171static const std::string sLayerNameTwo = "layer2";
172static constexpr const uid_t sUidOne = 0;
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700173static constexpr pid_t sPidOne = 10;
174static constexpr pid_t sPidTwo = 20;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000175static constexpr int32_t sInputEventId = 5;
Alec Mouri9a29e672020-09-14 12:39:14 -0700176
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700177TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
178 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000179 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700180 flushTokens(systemTime() + maxTokenRetentionTime);
181 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
182 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
183
184 // token1 should have expired
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000185 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700186 EXPECT_EQ(predictions.has_value(), false);
187
188 predictions = mTokenManager->getPredictionsForToken(token2);
189 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
190}
191
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700192TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000193 auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800194 sLayerNameOne, sLayerNameOne);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000195 auto surfaceFrame2 = mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800196 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700197 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
198 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
199}
200
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700201TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000202 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800203 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700204 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
205}
206
207TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
208 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
209 flushTokens(systemTime() + maxTokenRetentionTime);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000210 auto surfaceFrame =
211 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
212 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700213
214 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
215}
216
217TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
218 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000219 auto surfaceFrame =
220 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
221 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700222
223 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
224 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
225}
226
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000227TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
228 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
229 constexpr int32_t inputEventId = 1;
230 auto surfaceFrame =
231 mFrameTimeline->createSurfaceFrameForToken({token1, inputEventId}, sPidOne, sUidOne,
232 sLayerNameOne, sLayerNameOne);
233
234 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
235}
236
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700237TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
238 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700239 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000240 auto surfaceFrame1 =
241 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
242 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700243
244 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800245 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000246 surfaceFrame1->setDropTime(12);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800247 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
248 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700249 mFrameTimeline->setSfPresent(25, presentFence1);
250 presentFence1->signalForTest(30);
251
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000252 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700253
254 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
255 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000256 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
257 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700258 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
259}
260
261TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800262 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800263 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700264 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
265 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700266 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri9a29e672020-09-14 12:39:14 -0700267 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000268 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
269 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700270 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000271 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
272 sUidOne, sLayerNameTwo, sLayerNameTwo);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800273 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800274 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
275 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
276 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
277 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700278 mFrameTimeline->setSfPresent(26, presentFence1);
279 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800280 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
281 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700282 presentFence1->signalForTest(42);
283
284 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800285 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700286 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
287 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
288
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000289 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700290
291 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800292 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700293 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
294 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100295 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
296 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700297}
298
299TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
300 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
301 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800302 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800303 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800304 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700305 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700306 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
307 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
308 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
309 int64_t sfToken = mTokenManager->generateTokenForPredictions(
310 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700311 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000312 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId},
313 sPidOne, sUidOne, sLayerNameOne,
314 sLayerNameOne);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800315 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800316 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
317 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700318 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
319 presentFence->signalForTest(32 + frameTimeFactor);
320 frameTimeFactor += 30;
321 }
322 auto displayFrame0 = getDisplayFrame(0);
323
324 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800325 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700326
327 // Add one more display frame
328 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
329 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
330 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
331 int64_t sfToken = mTokenManager->generateTokenForPredictions(
332 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700333 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000334 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
335 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800336 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800337 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
338 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700339 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
340 presentFence->signalForTest(32 + frameTimeFactor);
341 displayFrame0 = getDisplayFrame(0);
342
343 // The window should have slided by 1 now and the previous 0th display frame
344 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800345 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700346}
347
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700348TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000349 auto surfaceFrame =
350 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, "acquireFenceAfterQueue",
351 "acquireFenceAfterQueue");
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700352 surfaceFrame->setActualQueueTime(123);
353 surfaceFrame->setAcquireFenceTime(456);
354 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
355}
356
357TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000358 auto surfaceFrame =
359 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, "acquireFenceAfterQueue",
360 "acquireFenceAfterQueue");
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700361 surfaceFrame->setActualQueueTime(456);
362 surfaceFrame->setAcquireFenceTime(123);
363 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
364}
365
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700366TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
367 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
368 presentFence->signalForTest(2);
369
370 // Size shouldn't exceed maxDisplayFrames - 64
371 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700372 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000373 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne,
374 sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700375 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800376 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800377 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
378 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700379 mFrameTimeline->setSfPresent(27, presentFence);
380 }
381 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
382
383 // Increase the size to 256
384 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000385 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700386
387 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700388 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000389 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne,
390 sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700391 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800392 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800393 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
394 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700395 mFrameTimeline->setSfPresent(27, presentFence);
396 }
397 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
398
399 // Shrink the size to 128
400 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000401 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700402
403 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700404 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000405 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerNameOne,
406 sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700407 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800408 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800409 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
410 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700411 mFrameTimeline->setSfPresent(27, presentFence);
412 }
413 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
414}
Alec Mouri9a29e672020-09-14 12:39:14 -0700415
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800416// Tests related to TimeStats
Alec Mouri9a29e672020-09-14 12:39:14 -0700417TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Alec Mouri363faf02021-01-29 16:34:55 -0800418 Fps refreshRate = Fps(11);
Alec Mouri9a29e672020-09-14 12:39:14 -0700419 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800420 incrementJankyFrames(
421 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
422 sLayerNameOne,
423 JankType::SurfaceFlingerCpuDeadlineMissed,
424 std::chrono::duration_cast<
425 std::chrono::nanoseconds>(3ms)
426 .count(),
427 std::chrono::duration_cast<
428 std::chrono::nanoseconds>(10ms)
429 .count(),
430 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700431 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
432 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
433 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
434 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
435 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
436 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
437 {std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
438 std::chrono::duration_cast<std::chrono::nanoseconds>(56ms).count(),
439 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
440 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000441 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
442 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700443 mFrameTimeline->setSfWakeUp(sfToken1,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800444 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
Alec Mouri363faf02021-01-29 16:34:55 -0800445 refreshRate);
446 surfaceFrame1->setAcquireFenceTime(
447 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count());
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800448 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
449 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700450 presentFence1->signalForTest(
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100451 std::chrono::duration_cast<std::chrono::nanoseconds>(70ms).count());
Alec Mouri9a29e672020-09-14 12:39:14 -0700452
453 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(59ms).count(),
454 presentFence1);
455}
456
457TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800458 Fps refreshRate = Fps::fromPeriodNsecs(30);
Alec Mouri9a29e672020-09-14 12:39:14 -0700459 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800460 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
461 sLayerNameOne, JankType::DisplayHAL,
462 0, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800463
Alec Mouri9a29e672020-09-14 12:39:14 -0700464 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
465 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
466 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
467 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
468 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
469 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
470 {std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
471 std::chrono::duration_cast<std::chrono::nanoseconds>(56ms).count(),
472 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
473 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000474 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
475 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700476 mFrameTimeline->setSfWakeUp(sfToken1,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800477 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
Alec Mouri363faf02021-01-29 16:34:55 -0800478 refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800479 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Alec Mouri363faf02021-01-29 16:34:55 -0800480 surfaceFrame1->setAcquireFenceTime(
481 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count());
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800482 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700483 presentFence1->signalForTest(
484 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count());
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800485 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(56ms).count(),
Alec Mouri9a29e672020-09-14 12:39:14 -0700486 presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800487 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700488}
489
490TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800491 Fps refreshRate = Fps(11.0);
Alec Mouri9a29e672020-09-14 12:39:14 -0700492 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800493 incrementJankyFrames(
494 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
495 sLayerNameOne, JankType::AppDeadlineMissed, 0, 0,
496 std::chrono::duration_cast<
497 std::chrono::nanoseconds>(25ms)
498 .count()}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700499 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
500 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
501 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
502 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
503 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
504 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800505 {std::chrono::duration_cast<std::chrono::nanoseconds>(82ms).count(),
506 std::chrono::duration_cast<std::chrono::nanoseconds>(86ms).count(),
507 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count()});
Alec Mouri9a29e672020-09-14 12:39:14 -0700508 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000509 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
510 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700511 surfaceFrame1->setAcquireFenceTime(
512 std::chrono::duration_cast<std::chrono::nanoseconds>(45ms).count());
513 mFrameTimeline->setSfWakeUp(sfToken1,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800514 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
Alec Mouri363faf02021-01-29 16:34:55 -0800515 refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700516
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800517 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
518 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700519 presentFence1->signalForTest(
520 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count());
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800521 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(86ms).count(),
Alec Mouri9a29e672020-09-14 12:39:14 -0700522 presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100523
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800524 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700525}
526
Alec Mouri363faf02021-01-29 16:34:55 -0800527TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
528 Fps refreshRate = Fps(11.0);
529 Fps renderRate = Fps(30.0);
530 EXPECT_CALL(*mTimeStats,
531 incrementJankyFrames(
532 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
533 JankType::AppDeadlineMissed, 0, 0,
534 std::chrono::duration_cast<
535 std::chrono::nanoseconds>(25ms)
536 .count()}));
537 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
538 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
539 {std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count(),
540 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count(),
541 std::chrono::duration_cast<std::chrono::nanoseconds>(60ms).count()});
542 int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
543 {std::chrono::duration_cast<std::chrono::nanoseconds>(82ms).count(),
544 std::chrono::duration_cast<std::chrono::nanoseconds>(86ms).count(),
545 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count()});
546 auto surfaceFrame1 =
547 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
548 sUidOne, sLayerNameOne, sLayerNameOne);
549 surfaceFrame1->setAcquireFenceTime(
550 std::chrono::duration_cast<std::chrono::nanoseconds>(45ms).count());
551 mFrameTimeline->setSfWakeUp(sfToken1,
552 std::chrono::duration_cast<std::chrono::nanoseconds>(52ms).count(),
553 refreshRate);
554
555 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
556 surfaceFrame1->setRenderRate(renderRate);
557 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
558 presentFence1->signalForTest(
559 std::chrono::duration_cast<std::chrono::nanoseconds>(90ms).count());
560 mFrameTimeline->setSfPresent(std::chrono::duration_cast<std::chrono::nanoseconds>(86ms).count(),
561 presentFence1);
562
563 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
564}
565
Adithya Srinivasan01189672020-10-20 14:23:05 -0700566/*
567 * Tracing Tests
568 *
569 * Trace packets are flushed all the way only when the next packet is traced.
570 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
571 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
572 * will have additional empty frames created for this reason.
573 */
574TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
575 auto tracingSession = getTracingSessionForTest();
576 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700577 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000578 auto surfaceFrame1 =
579 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
580 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700581
582 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800583 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800584 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
585 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700586 mFrameTimeline->setSfPresent(25, presentFence1);
587 presentFence1->signalForTest(30);
588
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000589 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700590
591 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000592 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700593}
594
595TEST_F(FrameTimelineTest, tracing_sanityTest) {
596 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800597 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800598 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700599 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700600
601 tracingSession->StartBlocking();
602 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
603 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000604 auto surfaceFrame1 =
605 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
606 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700607
608 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800609 mFrameTimeline->setSfWakeUp(token2, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800610 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
611 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700612 mFrameTimeline->setSfPresent(25, presentFence1);
613 presentFence1->signalForTest(30);
614
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000615 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000616 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700617 tracingSession->StopBlocking();
618
619 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000620 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000621 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700622}
623
624TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
625 auto tracingSession = getTracingSessionForTest();
626 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700627
628 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700629
630 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800631 mFrameTimeline->setSfWakeUp(-1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700632 mFrameTimeline->setSfPresent(25, presentFence1);
633 presentFence1->signalForTest(30);
634
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000635 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000636 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700637 tracingSession->StopBlocking();
638
639 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000640 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700641}
642
643TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
644 auto tracingSession = getTracingSessionForTest();
645 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700646
647 tracingSession->StartBlocking();
648 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000649 auto surfaceFrame1 = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne,
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800650 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700651
652 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800653 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800654 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
655 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700656 mFrameTimeline->setSfPresent(25, presentFence1);
657 presentFence1->signalForTest(30);
658
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000659 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000660 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700661 tracingSession->StopBlocking();
662
663 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000664 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
665 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000666 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700667}
668
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000669ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
670 pid_t pid) {
671 ProtoExpectedDisplayFrameStart proto;
672 proto.set_cookie(cookie);
673 proto.set_token(token);
674 proto.set_pid(pid);
675 return proto;
676}
677
678ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
679 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
680 bool gpuComposition, ProtoJankType jankType) {
681 ProtoActualDisplayFrameStart proto;
682 proto.set_cookie(cookie);
683 proto.set_token(token);
684 proto.set_pid(pid);
685 proto.set_present_type(presentType);
686 proto.set_on_time_finish(onTimeFinish);
687 proto.set_gpu_composition(gpuComposition);
688 proto.set_jank_type(jankType);
689 return proto;
690}
691
692ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
693 int64_t displayFrameToken,
694 pid_t pid,
695 std::string layerName) {
696 ProtoExpectedSurfaceFrameStart proto;
697 proto.set_cookie(cookie);
698 proto.set_token(token);
699 proto.set_display_frame_token(displayFrameToken);
700 proto.set_pid(pid);
701 proto.set_layer_name(layerName);
702 return proto;
703}
704
705ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
706 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
707 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
708 ProtoJankType jankType) {
709 ProtoActualSurfaceFrameStart proto;
710 proto.set_cookie(cookie);
711 proto.set_token(token);
712 proto.set_display_frame_token(displayFrameToken);
713 proto.set_pid(pid);
714 proto.set_layer_name(layerName);
715 proto.set_present_type(presentType);
716 proto.set_on_time_finish(onTimeFinish);
717 proto.set_gpu_composition(gpuComposition);
718 proto.set_jank_type(jankType);
719 return proto;
720}
721
722ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
723 ProtoFrameEnd proto;
724 proto.set_cookie(cookie);
725 return proto;
726}
727
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000728void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
729 const ProtoExpectedDisplayFrameStart& source) {
730 ASSERT_TRUE(received.has_cookie());
731 EXPECT_EQ(received.cookie(), source.cookie());
732
Adithya Srinivasan01189672020-10-20 14:23:05 -0700733 ASSERT_TRUE(received.has_token());
734 EXPECT_EQ(received.token(), source.token());
735
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000736 ASSERT_TRUE(received.has_pid());
737 EXPECT_EQ(received.pid(), source.pid());
738}
739
740void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
741 const ProtoActualDisplayFrameStart& source) {
742 ASSERT_TRUE(received.has_cookie());
743 EXPECT_EQ(received.cookie(), source.cookie());
744
745 ASSERT_TRUE(received.has_token());
746 EXPECT_EQ(received.token(), source.token());
747
748 ASSERT_TRUE(received.has_pid());
749 EXPECT_EQ(received.pid(), source.pid());
750
Adithya Srinivasan01189672020-10-20 14:23:05 -0700751 ASSERT_TRUE(received.has_present_type());
752 EXPECT_EQ(received.present_type(), source.present_type());
753 ASSERT_TRUE(received.has_on_time_finish());
754 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
755 ASSERT_TRUE(received.has_gpu_composition());
756 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
757 ASSERT_TRUE(received.has_jank_type());
758 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700759}
760
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000761void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
762 const ProtoExpectedSurfaceFrameStart& source) {
763 ASSERT_TRUE(received.has_cookie());
764 EXPECT_EQ(received.cookie(), source.cookie());
765
Adithya Srinivasan01189672020-10-20 14:23:05 -0700766 ASSERT_TRUE(received.has_token());
767 EXPECT_EQ(received.token(), source.token());
768
769 ASSERT_TRUE(received.has_display_frame_token());
770 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
771
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000772 ASSERT_TRUE(received.has_pid());
773 EXPECT_EQ(received.pid(), source.pid());
774
775 ASSERT_TRUE(received.has_layer_name());
776 EXPECT_EQ(received.layer_name(), source.layer_name());
777}
778
779void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
780 const ProtoActualSurfaceFrameStart& source) {
781 ASSERT_TRUE(received.has_cookie());
782 EXPECT_EQ(received.cookie(), source.cookie());
783
784 ASSERT_TRUE(received.has_token());
785 EXPECT_EQ(received.token(), source.token());
786
787 ASSERT_TRUE(received.has_display_frame_token());
788 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
789
790 ASSERT_TRUE(received.has_pid());
791 EXPECT_EQ(received.pid(), source.pid());
792
793 ASSERT_TRUE(received.has_layer_name());
794 EXPECT_EQ(received.layer_name(), source.layer_name());
795
Adithya Srinivasan01189672020-10-20 14:23:05 -0700796 ASSERT_TRUE(received.has_present_type());
797 EXPECT_EQ(received.present_type(), source.present_type());
798 ASSERT_TRUE(received.has_on_time_finish());
799 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
800 ASSERT_TRUE(received.has_gpu_composition());
801 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
802 ASSERT_TRUE(received.has_jank_type());
803 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000804}
Adithya Srinivasan01189672020-10-20 14:23:05 -0700805
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000806void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
807 ASSERT_TRUE(received.has_cookie());
808 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700809}
810
811TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
812 auto tracingSession = getTracingSessionForTest();
813 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700814
815 tracingSession->StartBlocking();
816 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -0700817
818 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800819 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700820 mFrameTimeline->setSfPresent(26, presentFence1);
821 presentFence1->signalForTest(31);
822
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000823 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000824 auto protoExpectedDisplayFrameStart =
825 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
826 kSurfaceFlingerPid);
827 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
828 auto protoActualDisplayFrameStart =
829 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
830 kSurfaceFlingerPid,
831 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
832 FrameTimelineEvent::JANK_NONE);
833 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000834
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000835 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000836 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700837 tracingSession->StopBlocking();
838
839 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000840 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700841
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000842 // Packet - 0 : ExpectedDisplayFrameStart
843 const auto& packet0 = packets[0];
844 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000845 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000846 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700847
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000848 const auto& event0 = packet0.frame_timeline_event();
849 ASSERT_TRUE(event0.has_expected_display_frame_start());
850 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
851 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
852
853 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
854 const auto& packet1 = packets[1];
855 ASSERT_TRUE(packet1.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000856 EXPECT_EQ(packet1.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000857 ASSERT_TRUE(packet1.has_frame_timeline_event());
858
859 const auto& event1 = packet1.frame_timeline_event();
860 ASSERT_TRUE(event1.has_frame_end());
861 const auto& expectedDisplayFrameEnd = event1.frame_end();
862 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
863
864 // Packet - 2 : ActualDisplayFrameStart
865 const auto& packet2 = packets[2];
866 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000867 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000868 ASSERT_TRUE(packet2.has_frame_timeline_event());
869
870 const auto& event2 = packet2.frame_timeline_event();
871 ASSERT_TRUE(event2.has_actual_display_frame_start());
872 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
873 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
874
875 // Packet - 3 : FrameEnd (ActualDisplayFrame)
876 const auto& packet3 = packets[3];
877 ASSERT_TRUE(packet3.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000878 EXPECT_EQ(packet3.timestamp(), 26u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000879 ASSERT_TRUE(packet3.has_frame_timeline_event());
880
881 const auto& event3 = packet3.frame_timeline_event();
882 ASSERT_TRUE(event3.has_frame_end());
883 const auto& actualDisplayFrameEnd = event3.frame_end();
884 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700885}
886
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000887TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
888 auto tracingSession = getTracingSessionForTest();
889 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
890
891 tracingSession->StartBlocking();
892 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
893 // Flush the token so that it would expire
894 flushTokens(systemTime() + maxTokenRetentionTime);
895
896 // Set up the display frame
897 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
898 mFrameTimeline->setSfPresent(26, presentFence1);
899 presentFence1->signalForTest(31);
900
901 int64_t traceCookie = snoopCurrentTraceCookie();
902
903 auto protoActualDisplayFrameStart =
904 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
905 kSurfaceFlingerPid,
906 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
907 false, FrameTimelineEvent::JANK_UNKNOWN);
908 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
909
910 addEmptyDisplayFrame();
911 flushTrace();
912 tracingSession->StopBlocking();
913
914 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
915 // Only actual timeline packets should be in the trace
916 EXPECT_EQ(packets.size(), 2u);
917
918 // Packet - 0 : ActualDisplayFrameStart
919 const auto& packet0 = packets[0];
920 ASSERT_TRUE(packet0.has_timestamp());
921 EXPECT_EQ(packet0.timestamp(), 20u);
922 ASSERT_TRUE(packet0.has_frame_timeline_event());
923
924 const auto& event0 = packet0.frame_timeline_event();
925 ASSERT_TRUE(event0.has_actual_display_frame_start());
926 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
927 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
928
929 // Packet - 1 : FrameEnd (ActualDisplayFrame)
930 const auto& packet1 = packets[1];
931 ASSERT_TRUE(packet1.has_timestamp());
932 EXPECT_EQ(packet1.timestamp(), 26u);
933 ASSERT_TRUE(packet1.has_frame_timeline_event());
934
935 const auto& event1 = packet1.frame_timeline_event();
936 ASSERT_TRUE(event1.has_frame_end());
937 const auto& actualDisplayFrameEnd = event1.frame_end();
938 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
939}
940
Adithya Srinivasan01189672020-10-20 14:23:05 -0700941TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
942 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800943 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800944 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700945 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
946 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
947
948 tracingSession->StartBlocking();
949 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
950 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -0700951
952 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000953 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
954 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000955 auto surfaceFrame2 =
956 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
957 sUidOne, sLayerNameOne, sLayerNameOne);
958 surfaceFrame1->setActualQueueTime(10);
959 surfaceFrame1->setDropTime(15);
960
961 surfaceFrame2->setActualQueueTime(15);
962 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700963
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000964 // First 2 cookies will be used by the DisplayFrame
965 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
966
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000967 auto protoDroppedSurfaceFrameExpectedStart =
968 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
969 displayFrameToken1, sPidOne, sLayerNameOne);
970 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
971 auto protoDroppedSurfaceFrameActualStart =
972 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
973 displayFrameToken1, sPidOne, sLayerNameOne,
974 FrameTimelineEvent::PRESENT_DROPPED, false, false,
975 FrameTimelineEvent::JANK_NONE);
976 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000977
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000978 auto protoPresentedSurfaceFrameExpectedStart =
979 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
980 displayFrameToken1, sPidOne, sLayerNameOne);
981 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
982 auto protoPresentedSurfaceFrameActualStart =
983 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
984 displayFrameToken1, sPidOne, sLayerNameOne,
985 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
986 FrameTimelineEvent::JANK_NONE);
987 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700988
989 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800990 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000991 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
992 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800993 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000994 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700995 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800996 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700997
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000998 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000999 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001000 tracingSession->StopBlocking();
1001
1002 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001003 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1004 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001005
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001006 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001007 const auto& packet4 = packets[4];
1008 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001009 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001010 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001011
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001012 const auto& event4 = packet4.frame_timeline_event();
1013 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001014 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1015 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001016
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001017 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001018 const auto& packet5 = packets[5];
1019 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001020 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001021 ASSERT_TRUE(packet5.has_frame_timeline_event());
1022
1023 const auto& event5 = packet5.frame_timeline_event();
1024 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001025 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1026 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001027
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001028 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001029 const auto& packet6 = packets[6];
1030 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001031 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001032 ASSERT_TRUE(packet6.has_frame_timeline_event());
1033
1034 const auto& event6 = packet6.frame_timeline_event();
1035 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001036 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1037 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001038
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001039 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001040 const auto& packet7 = packets[7];
1041 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001042 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001043 ASSERT_TRUE(packet7.has_frame_timeline_event());
1044
1045 const auto& event7 = packet7.frame_timeline_event();
1046 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001047 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1048 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1049
1050 // Packet - 8 : ExpectedSurfaceFrameStart2
1051 const auto& packet8 = packets[8];
1052 ASSERT_TRUE(packet8.has_timestamp());
1053 EXPECT_EQ(packet8.timestamp(), 10u);
1054 ASSERT_TRUE(packet8.has_frame_timeline_event());
1055
1056 const auto& event8 = packet8.frame_timeline_event();
1057 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1058 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1059 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1060
1061 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1062 const auto& packet9 = packets[9];
1063 ASSERT_TRUE(packet9.has_timestamp());
1064 EXPECT_EQ(packet9.timestamp(), 25u);
1065 ASSERT_TRUE(packet9.has_frame_timeline_event());
1066
1067 const auto& event9 = packet9.frame_timeline_event();
1068 ASSERT_TRUE(event9.has_frame_end());
1069 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1070 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1071
1072 // Packet - 10 : ActualSurfaceFrameStart2
1073 const auto& packet10 = packets[10];
1074 ASSERT_TRUE(packet10.has_timestamp());
1075 EXPECT_EQ(packet10.timestamp(), 10u);
1076 ASSERT_TRUE(packet10.has_frame_timeline_event());
1077
1078 const auto& event10 = packet10.frame_timeline_event();
1079 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1080 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1081 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1082
1083 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1084 const auto& packet11 = packets[11];
1085 ASSERT_TRUE(packet11.has_timestamp());
1086 EXPECT_EQ(packet11.timestamp(), 20u);
1087 ASSERT_TRUE(packet11.has_frame_timeline_event());
1088
1089 const auto& event11 = packet11.frame_timeline_event();
1090 ASSERT_TRUE(event11.has_frame_end());
1091 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1092 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1093}
1094
1095TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1096 auto tracingSession = getTracingSessionForTest();
1097 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1098
1099 tracingSession->StartBlocking();
1100 constexpr nsecs_t appStartTime =
1101 std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count();
1102 constexpr nsecs_t appEndTime =
1103 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count();
1104 constexpr nsecs_t appPresentTime =
1105 std::chrono::duration_cast<std::chrono::nanoseconds>(30ms).count();
1106 int64_t surfaceFrameToken =
1107 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1108
1109 // Flush the token so that it would expire
1110 flushTokens(systemTime() + maxTokenRetentionTime);
1111 auto surfaceFrame1 =
1112 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0},
1113 sPidOne, sUidOne, sLayerNameOne,
1114 sLayerNameOne);
1115 surfaceFrame1->setActualQueueTime(appEndTime);
1116 surfaceFrame1->setAcquireFenceTime(appEndTime);
1117
1118 constexpr nsecs_t sfStartTime =
1119 std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count();
1120 constexpr nsecs_t sfEndTime =
1121 std::chrono::duration_cast<std::chrono::nanoseconds>(30ms).count();
1122 constexpr nsecs_t sfPresentTime =
1123 std::chrono::duration_cast<std::chrono::nanoseconds>(30ms).count();
1124 int64_t displayFrameToken =
1125 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1126
1127 // First 2 cookies will be used by the DisplayFrame
1128 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1129
1130 auto protoActualSurfaceFrameStart =
1131 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1132 displayFrameToken, sPidOne, sLayerNameOne,
1133 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
1134 false, FrameTimelineEvent::JANK_UNKNOWN);
1135 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1136
1137 // Set up the display frame
1138 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1139 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1140 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1141 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1142 presentFence1->signalForTest(sfPresentTime);
1143
1144 addEmptyDisplayFrame();
1145 flushTrace();
1146 tracingSession->StopBlocking();
1147
1148 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1149 // Display Frame 4 packets + SurfaceFrame 2 packets
1150 ASSERT_EQ(packets.size(), 6u);
1151
1152 // Packet - 4 : ActualSurfaceFrameStart
1153 const auto& packet4 = packets[4];
1154 ASSERT_TRUE(packet4.has_timestamp());
1155 EXPECT_EQ(packet4.timestamp(),
1156 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1157 ASSERT_TRUE(packet4.has_frame_timeline_event());
1158
1159 const auto& event4 = packet4.frame_timeline_event();
1160 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1161 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1162 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1163
1164 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1165 const auto& packet5 = packets[5];
1166 ASSERT_TRUE(packet5.has_timestamp());
1167 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1168 ASSERT_TRUE(packet5.has_frame_timeline_event());
1169
1170 const auto& event5 = packet5.frame_timeline_event();
1171 ASSERT_TRUE(event5.has_frame_end());
1172 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001173 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001174}
1175
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001176// Tests for Jank classification
1177TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001178 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001179 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001180 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1181 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
1182 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
1183 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001184 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
1185 sUidOne, sLayerNameOne, sLayerNameOne);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001186 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001187 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1188 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1189 mFrameTimeline->setSfPresent(26, presentFence1);
1190 auto displayFrame = getDisplayFrame(0);
1191 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1192 presentFence1->signalForTest(29);
1193
1194 // Fences haven't been flushed yet, so it should be 0
1195 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1196 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1197
1198 addEmptyDisplayFrame();
1199 displayFrame = getDisplayFrame(0);
1200
1201 // Fences have flushed, so the present timestamps should be updated
1202 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1203 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1204 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1205 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1206 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
1207}
1208
1209TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001210 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001211 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1212 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1213 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001214 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001215 mFrameTimeline->setSfPresent(26, presentFence1);
1216 auto displayFrame = getDisplayFrame(0);
1217 presentFence1->signalForTest(30);
1218
1219 // Fences for the first frame haven't been flushed yet, so it should be 0
1220 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1221
1222 // Trigger a flush by finalizing the next DisplayFrame
1223 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001224 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001225 mFrameTimeline->setSfPresent(56, presentFence2);
1226 displayFrame = getDisplayFrame(0);
1227
1228 // Fences for the first frame have flushed, so the present timestamps should be updated
1229 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1230 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1231 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1232 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1233
1234 // Fences for the second frame haven't been flushed yet, so it should be 0
1235 auto displayFrame2 = getDisplayFrame(1);
1236 presentFence2->signalForTest(65);
1237 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001238 addEmptyDisplayFrame();
1239 displayFrame2 = getDisplayFrame(1);
1240
1241 // Fences for the second frame have flushed, so the present timestamps should be updated
1242 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1243 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1244 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1245 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1246}
1247
1248TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001249 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001250 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1251 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1252 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001253 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001254 mFrameTimeline->setSfPresent(26, presentFence1);
1255 auto displayFrame = getDisplayFrame(0);
1256 presentFence1->signalForTest(50);
1257
1258 // Fences for the first frame haven't been flushed yet, so it should be 0
1259 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1260
1261 // Trigger a flush by finalizing the next DisplayFrame
1262 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001263 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001264 mFrameTimeline->setSfPresent(56, presentFence2);
1265 displayFrame = getDisplayFrame(0);
1266
1267 // Fences for the first frame have flushed, so the present timestamps should be updated
1268 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1269 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1270 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1271 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1272
1273 // Fences for the second frame haven't been flushed yet, so it should be 0
1274 auto displayFrame2 = getDisplayFrame(1);
1275 presentFence2->signalForTest(75);
1276 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1277
1278 addEmptyDisplayFrame();
1279 displayFrame2 = getDisplayFrame(1);
1280
1281 // Fences for the second frame have flushed, so the present timestamps should be updated
1282 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1283 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1284 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1285 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1286}
1287
1288TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001289 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1290 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001291 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001292
1293 mFrameTimeline->setSfPresent(22, presentFence1);
1294 auto displayFrame = getDisplayFrame(0);
1295 presentFence1->signalForTest(28);
1296
1297 // Fences haven't been flushed yet, so it should be 0
1298 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1299
1300 addEmptyDisplayFrame();
1301 displayFrame = getDisplayFrame(0);
1302
1303 // Fences have flushed, so the present timestamps should be updated
1304 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1305 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1306 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1307 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1308}
1309
1310TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001311 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1312 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001313 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001314 mFrameTimeline->setSfPresent(36, presentFence1);
1315 auto displayFrame = getDisplayFrame(0);
1316 presentFence1->signalForTest(52);
1317
1318 // Fences haven't been flushed yet, so it should be 0
1319 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1320
1321 addEmptyDisplayFrame();
1322 displayFrame = getDisplayFrame(0);
1323
1324 // Fences have flushed, so the present timestamps should be updated
1325 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
1326 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1327 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1328 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1329}
1330
1331TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001332 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001333 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1334 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1335 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
1336 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1337 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1338 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001339 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1340 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001341 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001342 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001343 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1344 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1345 mFrameTimeline->setSfPresent(26, presentFence1);
1346 auto displayFrame1 = getDisplayFrame(0);
1347 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1348 presentFence1->signalForTest(30);
1349
1350 // Fences for the first frame haven't been flushed yet, so it should be 0
1351 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1352 auto actuals1 = presentedSurfaceFrame1.getActuals();
1353 EXPECT_EQ(actuals1.presentTime, 0);
1354
1355 // Trigger a flush by finalizing the next DisplayFrame
1356 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1357 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001358 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1359 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001360 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001361 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001362 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1363 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1364 mFrameTimeline->setSfPresent(56, presentFence2);
1365 auto displayFrame2 = getDisplayFrame(1);
1366 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1367
1368 // Fences for the first frame have flushed, so the present timestamps should be updated
1369 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1370 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1371 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1372 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1373
1374 actuals1 = presentedSurfaceFrame1.getActuals();
1375 EXPECT_EQ(actuals1.presentTime, 30);
1376 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1377 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1378 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1379
1380 // Fences for the second frame haven't been flushed yet, so it should be 0
1381 presentFence2->signalForTest(65);
1382 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1383 auto actuals2 = presentedSurfaceFrame2.getActuals();
1384 EXPECT_EQ(actuals2.presentTime, 0);
1385
Alec Mouri363faf02021-01-29 16:34:55 -08001386 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1387
1388 EXPECT_CALL(*mTimeStats,
1389 incrementJankyFrames(
1390 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
1391 sLayerNameOne, JankType::PredictionError, 0, 5,
1392 0}));
1393
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001394 addEmptyDisplayFrame();
1395
1396 // Fences for the second frame have flushed, so the present timestamps should be updated
1397 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1398 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1399 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1400 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1401
1402 actuals2 = presentedSurfaceFrame2.getActuals();
1403 EXPECT_EQ(actuals2.presentTime, 65);
1404 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1405 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1406 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1407}
1408
1409TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001410 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001411 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1412 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1413 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
1414 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1415 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1416 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001417 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1418 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001419 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001420 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001421 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1422 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1423 mFrameTimeline->setSfPresent(26, presentFence1);
1424 auto displayFrame1 = getDisplayFrame(0);
1425 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1426 presentFence1->signalForTest(50);
1427
1428 // Fences for the first frame haven't been flushed yet, so it should be 0
1429 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1430 auto actuals1 = presentedSurfaceFrame1.getActuals();
1431 EXPECT_EQ(actuals1.presentTime, 0);
1432
1433 // Trigger a flush by finalizing the next DisplayFrame
1434 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1435 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001436 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1437 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001438 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001439 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001440 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1441 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1442 mFrameTimeline->setSfPresent(56, presentFence2);
1443 auto displayFrame2 = getDisplayFrame(1);
1444 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1445
1446 // Fences for the first frame have flushed, so the present timestamps should be updated
1447 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1448 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1449 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1450 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1451
1452 actuals1 = presentedSurfaceFrame1.getActuals();
1453 EXPECT_EQ(actuals1.presentTime, 50);
1454 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1455 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1456 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1457
1458 // Fences for the second frame haven't been flushed yet, so it should be 0
1459 presentFence2->signalForTest(86);
1460 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1461 auto actuals2 = presentedSurfaceFrame2.getActuals();
1462 EXPECT_EQ(actuals2.presentTime, 0);
1463
Alec Mouri363faf02021-01-29 16:34:55 -08001464 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1465
1466 EXPECT_CALL(*mTimeStats,
1467 incrementJankyFrames(
1468 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
1469 sLayerNameOne, JankType::PredictionError, 0, 5,
1470 0}));
1471
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001472 addEmptyDisplayFrame();
1473
1474 // Fences for the second frame have flushed, so the present timestamps should be updated
1475 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1476 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1477 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1478 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1479
1480 actuals2 = presentedSurfaceFrame2.getActuals();
1481 EXPECT_EQ(actuals2.presentTime, 86);
1482 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1483 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1484 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1485}
1486
1487TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001488 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08001489
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001490 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1491 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 46, 50});
1492 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
1493 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001494 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1495 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001496 surfaceFrame1->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001497 mFrameTimeline->setSfWakeUp(sfToken1, 42, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001498 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1499 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1500 mFrameTimeline->setSfPresent(46, presentFence1);
1501 auto displayFrame1 = getDisplayFrame(0);
1502 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1503 presentFence1->signalForTest(50);
1504
1505 // Fences for the first frame haven't been flushed yet, so it should be 0
1506 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1507 auto actuals1 = presentedSurfaceFrame1.getActuals();
1508 EXPECT_EQ(actuals1.presentTime, 0);
1509
1510 addEmptyDisplayFrame();
1511
1512 // Fences for the first frame have flushed, so the present timestamps should be updated
1513 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1514 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1515 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1516 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1517
1518 actuals1 = presentedSurfaceFrame1.getActuals();
1519 EXPECT_EQ(actuals1.presentTime, 50);
1520 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1521 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1522 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
1523}
1524
1525TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
1526 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as
1527 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
1528 // jank to the SurfaceFrame.
1529
Alec Mouri363faf02021-01-29 16:34:55 -08001530 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001531 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1532 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 36, 40});
1533 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 46, 50});
1534 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1535 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
1536 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001537 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1538 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001539 surfaceFrame1->setAcquireFenceTime(26);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001540 mFrameTimeline->setSfWakeUp(sfToken1, 32, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001541 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1542 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1543 mFrameTimeline->setSfPresent(36, presentFence1);
1544 auto displayFrame1 = getDisplayFrame(0);
1545 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1546 presentFence1->signalForTest(40);
1547
1548 // Fences for the first frame haven't been flushed yet, so it should be 0
1549 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1550 auto actuals1 = presentedSurfaceFrame1.getActuals();
1551 EXPECT_EQ(actuals1.presentTime, 0);
1552
1553 // Trigger a flush by finalizing the next DisplayFrame
1554 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1555 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001556 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1557 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001558 surfaceFrame2->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001559 mFrameTimeline->setSfWakeUp(sfToken2, 43, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001560 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1561 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1562 mFrameTimeline->setSfPresent(56, presentFence2);
1563 auto displayFrame2 = getDisplayFrame(1);
1564 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1565
1566 // Fences for the first frame have flushed, so the present timestamps should be updated
1567 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
1568 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1569 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1570 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1571
1572 actuals1 = presentedSurfaceFrame1.getActuals();
1573 EXPECT_EQ(actuals1.presentTime, 40);
1574 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1575 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1576 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1577
1578 // Fences for the second frame haven't been flushed yet, so it should be 0
1579 presentFence2->signalForTest(60);
1580 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1581 auto actuals2 = presentedSurfaceFrame2.getActuals();
1582 EXPECT_EQ(actuals2.presentTime, 0);
1583
1584 addEmptyDisplayFrame();
1585
1586 // Fences for the second frame have flushed, so the present timestamps should be updated
1587 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
1588 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1589 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1590 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1591
1592 actuals2 = presentedSurfaceFrame2.getActuals();
1593 EXPECT_EQ(actuals2.presentTime, 60);
1594 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1595 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1596 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1597}
1598
1599TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001600 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001601 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001602 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1603 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
1604 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
1605
1606 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 56, 60});
1607 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 116, 120});
1608 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001609 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1610 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001611 surfaceFrame1->setAcquireFenceTime(50);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001612 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001613 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1614 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1615 mFrameTimeline->setSfPresent(56, presentFence1);
1616 auto displayFrame1 = getDisplayFrame(0);
1617 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1618 presentFence1->signalForTest(60);
1619
1620 // Fences for the first frame haven't been flushed yet, so it should be 0
1621 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1622 auto actuals1 = presentedSurfaceFrame1.getActuals();
1623 EXPECT_EQ(actuals1.presentTime, 0);
1624
1625 // Trigger a flush by finalizing the next DisplayFrame
1626 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1627 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001628 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1629 sUidOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001630 surfaceFrame2->setAcquireFenceTime(84);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001631 mFrameTimeline->setSfWakeUp(sfToken2, 112, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001632 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
1633 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1634 mFrameTimeline->setSfPresent(116, presentFence2);
1635 auto displayFrame2 = getDisplayFrame(1);
1636 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1637 presentFence2->signalForTest(120);
1638
1639 // Fences for the first frame have flushed, so the present timestamps should be updated
1640 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
1641 actuals1 = presentedSurfaceFrame1.getActuals();
1642 EXPECT_EQ(actuals1.endTime, 50);
1643 EXPECT_EQ(actuals1.presentTime, 60);
1644
1645 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1646 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1647 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1648
1649 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1650 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1651 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1652
1653 // Fences for the second frame haven't been flushed yet, so it should be 0
1654 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1655 auto actuals2 = presentedSurfaceFrame2.getActuals();
1656 EXPECT_EQ(actuals2.presentTime, 0);
1657
1658 addEmptyDisplayFrame();
1659
1660 // Fences for the second frame have flushed, so the present timestamps should be updated
1661 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1662 actuals2 = presentedSurfaceFrame2.getActuals();
1663 EXPECT_EQ(actuals2.presentTime, 120);
1664
1665 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1666 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1667 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
1668
1669 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1670 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1671 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
1672 JankType::AppDeadlineMissed | JankType::BufferStuffing);
1673}
Adithya Srinivasanf279e042020-08-17 14:56:27 -07001674} // namespace android::frametimeline