blob: 0ef237338743314a3458d99d9ea329bbb379d609 [file] [log] [blame]
Adithya Srinivasanf279e042020-08-17 14:56:27 -07001/*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Marin Shalamanovbed7fd32020-12-21 20:02:20 +010017
Alec Mouri9a29e672020-09-14 12:39:14 -070018#include "gmock/gmock-spec-builders.h"
19#include "mock/MockTimeStats.h"
Adithya Srinivasanf279e042020-08-17 14:56:27 -070020#undef LOG_TAG
21#define LOG_TAG "LibSurfaceFlingerUnittests"
22
23#include <FrameTimeline/FrameTimeline.h>
24#include <gtest/gtest.h>
25#include <log/log.h>
Adithya Srinivasan01189672020-10-20 14:23:05 -070026#include <perfetto/trace/trace.pb.h>
Adithya Srinivasanf279e042020-08-17 14:56:27 -070027#include <cinttypes>
28
29using namespace std::chrono_literals;
Alec Mouri363faf02021-01-29 16:34:55 -080030using testing::_;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -080031using testing::AtLeast;
Alec Mouri9a29e672020-09-14 12:39:14 -070032using testing::Contains;
Adithya Srinivasan01189672020-10-20 14:23:05 -070033using FrameTimelineEvent = perfetto::protos::FrameTimelineEvent;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000034using ProtoExpectedDisplayFrameStart =
35 perfetto::protos::FrameTimelineEvent_ExpectedDisplayFrameStart;
36using ProtoExpectedSurfaceFrameStart =
37 perfetto::protos::FrameTimelineEvent_ExpectedSurfaceFrameStart;
38using ProtoActualDisplayFrameStart = perfetto::protos::FrameTimelineEvent_ActualDisplayFrameStart;
39using ProtoActualSurfaceFrameStart = perfetto::protos::FrameTimelineEvent_ActualSurfaceFrameStart;
40using ProtoFrameEnd = perfetto::protos::FrameTimelineEvent_FrameEnd;
Adithya Srinivasan01189672020-10-20 14:23:05 -070041using ProtoPresentType = perfetto::protos::FrameTimelineEvent_PresentType;
42using ProtoJankType = perfetto::protos::FrameTimelineEvent_JankType;
Adithya Srinivasan78e58af2021-02-25 00:08:08 +000043using ProtoPredictionType = perfetto::protos::FrameTimelineEvent_PredictionType;
Alec Mouri9a29e672020-09-14 12:39:14 -070044
Adithya Srinivasanf279e042020-08-17 14:56:27 -070045namespace android::frametimeline {
46
47class FrameTimelineTest : public testing::Test {
48public:
49 FrameTimelineTest() {
50 const ::testing::TestInfo* const test_info =
51 ::testing::UnitTest::GetInstance()->current_test_info();
52 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
53 }
54
55 ~FrameTimelineTest() {
56 const ::testing::TestInfo* const test_info =
57 ::testing::UnitTest::GetInstance()->current_test_info();
58 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
59 }
60
Adithya Srinivasan01189672020-10-20 14:23:05 -070061 static void SetUpTestSuite() {
62 // Need to initialize tracing in process for testing, and only once per test suite.
63 perfetto::TracingInitArgs args;
64 args.backends = perfetto::kInProcessBackend;
65 perfetto::Tracing::Initialize(args);
66 }
67
Adithya Srinivasanf279e042020-08-17 14:56:27 -070068 void SetUp() override {
Alec Mouri9a29e672020-09-14 12:39:14 -070069 mTimeStats = std::make_shared<mock::TimeStats>();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000070 mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats, kSurfaceFlingerPid,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +000071 kTestThresholds, kHwcDuration);
Adithya Srinivasan01189672020-10-20 14:23:05 -070072 mFrameTimeline->registerDataSource();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070073 mTokenManager = &mFrameTimeline->mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000074 mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
Adithya Srinivasan2d736322020-10-01 16:53:48 -070075 maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070076 maxTokenRetentionTime = mTokenManager->kMaxRetentionTime;
77 }
78
Adithya Srinivasan01189672020-10-20 14:23:05 -070079 // Each tracing session can be used for a single block of Start -> Stop.
80 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
81 perfetto::TraceConfig cfg;
82 cfg.set_duration_ms(500);
83 cfg.add_buffers()->set_size_kb(1024);
84 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
85 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
86
87 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
88 tracingSession->Setup(cfg);
89 return tracingSession;
90 }
91
92 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
93 perfetto::TracingSession* tracingSession) {
94 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
95 perfetto::protos::Trace trace;
96 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
97
98 std::vector<perfetto::protos::TracePacket> packets;
99 for (const auto& packet : trace.packet()) {
100 if (!packet.has_frame_timeline_event()) {
101 continue;
102 }
103 packets.emplace_back(packet);
104 }
105 return packets;
106 }
107
108 void addEmptyDisplayFrame() {
109 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000110 // Trigger a flushPresentFence by calling setSfPresent for the next frame
Adithya Srinivasan01189672020-10-20 14:23:05 -0700111 mFrameTimeline->setSfPresent(2500, presentFence1);
112 }
113
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700114 void flushTokens(nsecs_t flushTime) {
115 std::lock_guard<std::mutex> lock(mTokenManager->mMutex);
116 mTokenManager->flushTokens(flushTime);
117 }
118
119 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
120 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800121 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
122 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700123 }
124
125 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
126 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
127 return mFrameTimeline->mDisplayFrames[idx];
128 }
129
130 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
131 return a.startTime == b.startTime && a.endTime == b.endTime &&
132 a.presentTime == b.presentTime;
133 }
134
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000135 const std::map<int64_t, TokenManagerPrediction>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700136 return mTokenManager->mPredictions;
137 }
138
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000139 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700140 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
141 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
142 }
143
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000144 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
145
146 void flushTrace() {
147 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
148 FrameTimelineDataSource::Trace(
149 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
150 }
151
Alec Mouri9a29e672020-09-14 12:39:14 -0700152 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700153 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
154 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000155 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700156 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700157 uint32_t* maxDisplayFrames;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700158 nsecs_t maxTokenRetentionTime;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000159 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasanead17162021-02-18 02:17:37 +0000160 static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count();
161 static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(2ns).count();
162 static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800163 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
164 kDeadlineThreshold,
165 kStartThreshold};
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000166 static constexpr nsecs_t kHwcDuration = std::chrono::nanoseconds(3ns).count();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700167};
168
Alec Mouri9a29e672020-09-14 12:39:14 -0700169static const std::string sLayerNameOne = "layer1";
170static const std::string sLayerNameTwo = "layer2";
171static constexpr const uid_t sUidOne = 0;
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700172static constexpr pid_t sPidOne = 10;
173static constexpr pid_t sPidTwo = 20;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000174static constexpr int32_t sInputEventId = 5;
Alec Mouriadebf5c2021-01-05 12:57:36 -0800175static constexpr int32_t sLayerIdOne = 1;
176static constexpr int32_t sLayerIdTwo = 2;
Alec Mouri9a29e672020-09-14 12:39:14 -0700177
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700178TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
179 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000180 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700181 flushTokens(systemTime() + maxTokenRetentionTime);
182 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
183 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
184
185 // token1 should have expired
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000186 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700187 EXPECT_EQ(predictions.has_value(), false);
188
189 predictions = mTokenManager->getPredictionsForToken(token2);
190 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
191}
192
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700193TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800194 auto surfaceFrame1 =
195 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
196 sLayerNameOne, sLayerNameOne);
197 auto surfaceFrame2 =
198 mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerIdOne,
199 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700200 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
201 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
202}
203
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700204TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800205 auto surfaceFrame =
206 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
207 sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700208 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
209}
210
211TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
212 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
213 flushTokens(systemTime() + maxTokenRetentionTime);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000214 auto surfaceFrame =
215 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800216 sLayerIdOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700217
218 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
219}
220
221TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
222 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000223 auto surfaceFrame =
224 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800225 sLayerIdOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700226
227 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
228 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
229}
230
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000231TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
232 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
233 constexpr int32_t inputEventId = 1;
234 auto surfaceFrame =
235 mFrameTimeline->createSurfaceFrameForToken({token1, inputEventId}, sPidOne, sUidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800236 sLayerIdOne, sLayerNameOne, sLayerNameOne);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000237
238 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
239}
240
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700241TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
242 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700243 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000244 auto surfaceFrame1 =
245 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800246 sLayerIdOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700247
248 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800249 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000250 surfaceFrame1->setDropTime(12);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800251 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
252 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700253 mFrameTimeline->setSfPresent(25, presentFence1);
254 presentFence1->signalForTest(30);
255
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000256 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700257
258 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
259 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000260 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
261 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700262 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
263}
264
265TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800266 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800267 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700268 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
269 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700270 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri9a29e672020-09-14 12:39:14 -0700271 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000272 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800273 sUidOne, sLayerIdOne, sLayerNameOne,
274 sLayerNameOne);
Alec Mouri9a29e672020-09-14 12:39:14 -0700275 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000276 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800277 sUidOne, sLayerIdTwo, sLayerNameTwo,
278 sLayerNameTwo);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800279 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800280 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
281 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
282 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
283 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700284 mFrameTimeline->setSfPresent(26, presentFence1);
285 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800286 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
287 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700288 presentFence1->signalForTest(42);
289
290 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800291 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700292 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
293 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
294
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000295 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700296
297 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800298 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700299 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
300 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100301 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
302 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700303}
304
305TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
306 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
307 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800308 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800309 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800310 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700311 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700312 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
313 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
314 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
315 int64_t sfToken = mTokenManager->generateTokenForPredictions(
316 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700317 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000318 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId},
Alec Mouriadebf5c2021-01-05 12:57:36 -0800319 sPidOne, sUidOne, sLayerIdOne,
320 sLayerNameOne, sLayerNameOne);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800321 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800322 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
323 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700324 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
325 presentFence->signalForTest(32 + frameTimeFactor);
326 frameTimeFactor += 30;
327 }
328 auto displayFrame0 = getDisplayFrame(0);
329
330 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800331 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700332
333 // Add one more display frame
334 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
335 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
336 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
337 int64_t sfToken = mTokenManager->generateTokenForPredictions(
338 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700339 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000340 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800341 sUidOne, sLayerIdOne, sLayerNameOne,
342 sLayerNameOne);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800343 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800344 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
345 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700346 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
347 presentFence->signalForTest(32 + frameTimeFactor);
348 displayFrame0 = getDisplayFrame(0);
349
350 // The window should have slided by 1 now and the previous 0th display frame
351 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800352 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700353}
354
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700355TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800356 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
357 "acquireFenceAfterQueue",
358 "acquireFenceAfterQueue");
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700359 surfaceFrame->setActualQueueTime(123);
360 surfaceFrame->setAcquireFenceTime(456);
361 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
362}
363
364TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800365 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
366 "acquireFenceAfterQueue",
367 "acquireFenceAfterQueue");
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700368 surfaceFrame->setActualQueueTime(456);
369 surfaceFrame->setAcquireFenceTime(123);
370 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
371}
372
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700373TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
374 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
375 presentFence->signalForTest(2);
376
377 // Size shouldn't exceed maxDisplayFrames - 64
378 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700379 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800380 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
381 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700382 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800383 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800384 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
385 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700386 mFrameTimeline->setSfPresent(27, presentFence);
387 }
388 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
389
390 // Increase the size to 256
391 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000392 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700393
394 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700395 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800396 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
397 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700398 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800399 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800400 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
401 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700402 mFrameTimeline->setSfPresent(27, presentFence);
403 }
404 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
405
406 // Shrink the size to 128
407 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000408 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700409
410 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700411 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800412 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
413 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700414 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800415 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800416 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
417 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700418 mFrameTimeline->setSfPresent(27, presentFence);
419 }
420 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
421}
Alec Mouri9a29e672020-09-14 12:39:14 -0700422
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800423// Tests related to TimeStats
Alec Mouri9a29e672020-09-14 12:39:14 -0700424TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000425 Fps refreshRate = Fps::fromPeriodNsecs(11);
426 // Deadline delta is 2ms because, sf's adjusted deadline is 60 - composerTime(3) = 57ms.
Alec Mouri9a29e672020-09-14 12:39:14 -0700427 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800428 incrementJankyFrames(
429 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
430 sLayerNameOne,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000431 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800432 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700433 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000434 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
435 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
436
Alec Mouri9a29e672020-09-14 12:39:14 -0700437 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000438 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800439 sUidOne, sLayerIdOne, sLayerNameOne,
440 sLayerNameOne);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000441 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
442 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800443 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
444 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000445 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700446
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000447 mFrameTimeline->setSfPresent(59, presentFence1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700448}
449
450TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800451 Fps refreshRate = Fps::fromPeriodNsecs(30);
Alec Mouri9a29e672020-09-14 12:39:14 -0700452 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800453 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
454 sLayerNameOne, JankType::DisplayHAL,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000455 -1, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800456
Alec Mouri9a29e672020-09-14 12:39:14 -0700457 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000458 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
459 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
460
Alec Mouri9a29e672020-09-14 12:39:14 -0700461 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000462 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800463 sUidOne, sLayerIdOne, sLayerNameOne,
464 sLayerNameOne);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000465 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800466 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000467 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800468 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000469 presentFence1->signalForTest(90);
470 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800471 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700472}
473
474TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800475 Fps refreshRate = Fps(11.0);
Alec Mouri9a29e672020-09-14 12:39:14 -0700476 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000477 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
478 sLayerNameOne,
479 JankType::AppDeadlineMissed, -1, 0,
480 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700481 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000482 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
483 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
484
Alec Mouri9a29e672020-09-14 12:39:14 -0700485 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000486 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800487 sUidOne, sLayerIdOne, sLayerNameOne,
488 sLayerNameOne);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000489 surfaceFrame1->setAcquireFenceTime(45);
490 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700491
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800492 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
493 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000494 presentFence1->signalForTest(90);
495 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100496
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800497 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700498}
499
Adithya Srinivasanead17162021-02-18 02:17:37 +0000500TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000501 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000502 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000503 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
504 sLayerNameOne,
505 JankType::SurfaceFlingerScheduling,
506 -1, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000507 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000508 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
509 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
510
Adithya Srinivasanead17162021-02-18 02:17:37 +0000511 auto surfaceFrame1 =
512 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800513 sUidOne, sLayerIdOne, sLayerNameOne,
514 sLayerNameOne);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000515 surfaceFrame1->setAcquireFenceTime(50);
516 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000517
518 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
519 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000520 presentFence1->signalForTest(60);
521 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000522
523 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
524}
525
526TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000527 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000528 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000529 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
530 sLayerNameOne,
531 JankType::PredictionError, -1, 5,
532 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000533 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000534 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
535 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
536
Adithya Srinivasanead17162021-02-18 02:17:37 +0000537 auto surfaceFrame1 =
538 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800539 sUidOne, sLayerIdOne, sLayerNameOne,
540 sLayerNameOne);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000541 surfaceFrame1->setAcquireFenceTime(40);
542 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000543
544 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
545 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000546 presentFence1->signalForTest(65);
547 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000548
549 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
550}
551
552TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000553 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000554 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000555 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
556 sLayerNameOne,
557 JankType::BufferStuffing, -1, 0,
558 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000559 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000560 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
561 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
562
Adithya Srinivasanead17162021-02-18 02:17:37 +0000563 auto surfaceFrame1 =
564 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800565 sUidOne, sLayerIdOne, sLayerNameOne,
566 sLayerNameOne);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000567 surfaceFrame1->setAcquireFenceTime(40);
568 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000569
570 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000571 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000572 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000573 presentFence1->signalForTest(90);
574 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000575
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000576 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000577}
578
Alec Mouri363faf02021-01-29 16:34:55 -0800579TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000580 Fps refreshRate = Fps::fromPeriodNsecs(11);
581 Fps renderRate = Fps::fromPeriodNsecs(30);
Alec Mouri363faf02021-01-29 16:34:55 -0800582 EXPECT_CALL(*mTimeStats,
583 incrementJankyFrames(
584 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000585 JankType::AppDeadlineMissed, -1, 0, 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800586 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000587 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
588 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
589
Alec Mouri363faf02021-01-29 16:34:55 -0800590 auto surfaceFrame1 =
591 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800592 sUidOne, sLayerIdOne, sLayerNameOne,
593 sLayerNameOne);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000594 surfaceFrame1->setAcquireFenceTime(45);
595 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800596
597 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
598 surfaceFrame1->setRenderRate(renderRate);
599 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000600 presentFence1->signalForTest(90);
601 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800602
603 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
604}
605
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000606TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
607 Fps refreshRate = Fps::fromPeriodNsecs(11);
608 Fps renderRate = Fps::fromPeriodNsecs(30);
609
610 EXPECT_CALL(*mTimeStats,
611 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne,
612 sLayerNameOne, JankType::Unknown,
613 -1, -1, 25}));
614 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
615 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
616 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
617
618 auto surfaceFrame1 =
619 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
620 sUidOne, sLayerIdOne, sLayerNameOne,
621 sLayerNameOne);
622 surfaceFrame1->setAcquireFenceTime(45);
623 // Trigger a prediction expiry
624 flushTokens(systemTime() + maxTokenRetentionTime);
625 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
626
627 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
628 surfaceFrame1->setRenderRate(renderRate);
629 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
630 presentFence1->signalForTest(90);
631 mFrameTimeline->setSfPresent(86, presentFence1);
632
633 auto displayFrame = getDisplayFrame(0);
634 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
635 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
636 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
637 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
638
639 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
640 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
641}
642
Adithya Srinivasan01189672020-10-20 14:23:05 -0700643/*
644 * Tracing Tests
645 *
646 * Trace packets are flushed all the way only when the next packet is traced.
647 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
648 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
649 * will have additional empty frames created for this reason.
650 */
651TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
652 auto tracingSession = getTracingSessionForTest();
653 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700654 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000655 auto surfaceFrame1 =
656 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800657 sLayerIdOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700658
659 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800660 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800661 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
662 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700663 mFrameTimeline->setSfPresent(25, presentFence1);
664 presentFence1->signalForTest(30);
665
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000666 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700667
668 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000669 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700670}
671
672TEST_F(FrameTimelineTest, tracing_sanityTest) {
673 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800674 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800675 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700676 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700677
678 tracingSession->StartBlocking();
679 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
680 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000681 auto surfaceFrame1 =
682 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800683 sLayerIdOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700684
685 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800686 mFrameTimeline->setSfWakeUp(token2, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800687 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
688 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700689 mFrameTimeline->setSfPresent(25, presentFence1);
690 presentFence1->signalForTest(30);
691
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000692 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000693 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700694 tracingSession->StopBlocking();
695
696 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000697 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000698 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700699}
700
701TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
702 auto tracingSession = getTracingSessionForTest();
703 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700704
705 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700706
707 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800708 mFrameTimeline->setSfWakeUp(-1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700709 mFrameTimeline->setSfPresent(25, presentFence1);
710 presentFence1->signalForTest(30);
711
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000712 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000713 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700714 tracingSession->StopBlocking();
715
716 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000717 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700718}
719
720TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
721 auto tracingSession = getTracingSessionForTest();
722 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700723
724 tracingSession->StartBlocking();
725 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -0800726 auto surfaceFrame1 =
727 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
728 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700729
730 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800731 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800732 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
733 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700734 mFrameTimeline->setSfPresent(25, presentFence1);
735 presentFence1->signalForTest(30);
736
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000737 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000738 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700739 tracingSession->StopBlocking();
740
741 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000742 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
743 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000744 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700745}
746
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000747ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
748 pid_t pid) {
749 ProtoExpectedDisplayFrameStart proto;
750 proto.set_cookie(cookie);
751 proto.set_token(token);
752 proto.set_pid(pid);
753 return proto;
754}
755
756ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
757 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000758 bool gpuComposition, ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000759 ProtoActualDisplayFrameStart proto;
760 proto.set_cookie(cookie);
761 proto.set_token(token);
762 proto.set_pid(pid);
763 proto.set_present_type(presentType);
764 proto.set_on_time_finish(onTimeFinish);
765 proto.set_gpu_composition(gpuComposition);
766 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000767 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000768 return proto;
769}
770
771ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
772 int64_t displayFrameToken,
773 pid_t pid,
774 std::string layerName) {
775 ProtoExpectedSurfaceFrameStart proto;
776 proto.set_cookie(cookie);
777 proto.set_token(token);
778 proto.set_display_frame_token(displayFrameToken);
779 proto.set_pid(pid);
780 proto.set_layer_name(layerName);
781 return proto;
782}
783
784ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
785 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
786 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000787 ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000788 ProtoActualSurfaceFrameStart proto;
789 proto.set_cookie(cookie);
790 proto.set_token(token);
791 proto.set_display_frame_token(displayFrameToken);
792 proto.set_pid(pid);
793 proto.set_layer_name(layerName);
794 proto.set_present_type(presentType);
795 proto.set_on_time_finish(onTimeFinish);
796 proto.set_gpu_composition(gpuComposition);
797 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000798 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000799 return proto;
800}
801
802ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
803 ProtoFrameEnd proto;
804 proto.set_cookie(cookie);
805 return proto;
806}
807
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000808void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
809 const ProtoExpectedDisplayFrameStart& source) {
810 ASSERT_TRUE(received.has_cookie());
811 EXPECT_EQ(received.cookie(), source.cookie());
812
Adithya Srinivasan01189672020-10-20 14:23:05 -0700813 ASSERT_TRUE(received.has_token());
814 EXPECT_EQ(received.token(), source.token());
815
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000816 ASSERT_TRUE(received.has_pid());
817 EXPECT_EQ(received.pid(), source.pid());
818}
819
820void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
821 const ProtoActualDisplayFrameStart& source) {
822 ASSERT_TRUE(received.has_cookie());
823 EXPECT_EQ(received.cookie(), source.cookie());
824
825 ASSERT_TRUE(received.has_token());
826 EXPECT_EQ(received.token(), source.token());
827
828 ASSERT_TRUE(received.has_pid());
829 EXPECT_EQ(received.pid(), source.pid());
830
Adithya Srinivasan01189672020-10-20 14:23:05 -0700831 ASSERT_TRUE(received.has_present_type());
832 EXPECT_EQ(received.present_type(), source.present_type());
833 ASSERT_TRUE(received.has_on_time_finish());
834 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
835 ASSERT_TRUE(received.has_gpu_composition());
836 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
837 ASSERT_TRUE(received.has_jank_type());
838 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000839 ASSERT_TRUE(received.has_prediction_type());
840 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700841}
842
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000843void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
844 const ProtoExpectedSurfaceFrameStart& source) {
845 ASSERT_TRUE(received.has_cookie());
846 EXPECT_EQ(received.cookie(), source.cookie());
847
Adithya Srinivasan01189672020-10-20 14:23:05 -0700848 ASSERT_TRUE(received.has_token());
849 EXPECT_EQ(received.token(), source.token());
850
851 ASSERT_TRUE(received.has_display_frame_token());
852 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
853
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000854 ASSERT_TRUE(received.has_pid());
855 EXPECT_EQ(received.pid(), source.pid());
856
857 ASSERT_TRUE(received.has_layer_name());
858 EXPECT_EQ(received.layer_name(), source.layer_name());
859}
860
861void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
862 const ProtoActualSurfaceFrameStart& source) {
863 ASSERT_TRUE(received.has_cookie());
864 EXPECT_EQ(received.cookie(), source.cookie());
865
866 ASSERT_TRUE(received.has_token());
867 EXPECT_EQ(received.token(), source.token());
868
869 ASSERT_TRUE(received.has_display_frame_token());
870 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
871
872 ASSERT_TRUE(received.has_pid());
873 EXPECT_EQ(received.pid(), source.pid());
874
875 ASSERT_TRUE(received.has_layer_name());
876 EXPECT_EQ(received.layer_name(), source.layer_name());
877
Adithya Srinivasan01189672020-10-20 14:23:05 -0700878 ASSERT_TRUE(received.has_present_type());
879 EXPECT_EQ(received.present_type(), source.present_type());
880 ASSERT_TRUE(received.has_on_time_finish());
881 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
882 ASSERT_TRUE(received.has_gpu_composition());
883 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
884 ASSERT_TRUE(received.has_jank_type());
885 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000886 ASSERT_TRUE(received.has_prediction_type());
887 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000888}
Adithya Srinivasan01189672020-10-20 14:23:05 -0700889
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000890void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
891 ASSERT_TRUE(received.has_cookie());
892 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700893}
894
895TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
896 auto tracingSession = getTracingSessionForTest();
897 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700898
899 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000900 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -0700901
902 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800903 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700904 mFrameTimeline->setSfPresent(26, presentFence1);
905 presentFence1->signalForTest(31);
906
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000907 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000908 auto protoExpectedDisplayFrameStart =
909 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
910 kSurfaceFlingerPid);
911 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
912 auto protoActualDisplayFrameStart =
913 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
914 kSurfaceFlingerPid,
915 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000916 FrameTimelineEvent::JANK_NONE,
917 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000918 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000919
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000920 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000921 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700922 tracingSession->StopBlocking();
923
924 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000925 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700926
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000927 // Packet - 0 : ExpectedDisplayFrameStart
928 const auto& packet0 = packets[0];
929 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000930 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000931 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700932
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000933 const auto& event0 = packet0.frame_timeline_event();
934 ASSERT_TRUE(event0.has_expected_display_frame_start());
935 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
936 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
937
938 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
939 const auto& packet1 = packets[1];
940 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000941 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000942 ASSERT_TRUE(packet1.has_frame_timeline_event());
943
944 const auto& event1 = packet1.frame_timeline_event();
945 ASSERT_TRUE(event1.has_frame_end());
946 const auto& expectedDisplayFrameEnd = event1.frame_end();
947 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
948
949 // Packet - 2 : ActualDisplayFrameStart
950 const auto& packet2 = packets[2];
951 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000952 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000953 ASSERT_TRUE(packet2.has_frame_timeline_event());
954
955 const auto& event2 = packet2.frame_timeline_event();
956 ASSERT_TRUE(event2.has_actual_display_frame_start());
957 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
958 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
959
960 // Packet - 3 : FrameEnd (ActualDisplayFrame)
961 const auto& packet3 = packets[3];
962 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +0000963 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000964 ASSERT_TRUE(packet3.has_frame_timeline_event());
965
966 const auto& event3 = packet3.frame_timeline_event();
967 ASSERT_TRUE(event3.has_frame_end());
968 const auto& actualDisplayFrameEnd = event3.frame_end();
969 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700970}
971
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000972TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
973 auto tracingSession = getTracingSessionForTest();
974 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
975
976 tracingSession->StartBlocking();
977 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
978 // Flush the token so that it would expire
979 flushTokens(systemTime() + maxTokenRetentionTime);
980
981 // Set up the display frame
982 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
983 mFrameTimeline->setSfPresent(26, presentFence1);
984 presentFence1->signalForTest(31);
985
986 int64_t traceCookie = snoopCurrentTraceCookie();
987
988 auto protoActualDisplayFrameStart =
989 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
990 kSurfaceFlingerPid,
991 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000992 false, FrameTimelineEvent::JANK_UNKNOWN,
993 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000994 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
995
996 addEmptyDisplayFrame();
997 flushTrace();
998 tracingSession->StopBlocking();
999
1000 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1001 // Only actual timeline packets should be in the trace
1002 EXPECT_EQ(packets.size(), 2u);
1003
1004 // Packet - 0 : ActualDisplayFrameStart
1005 const auto& packet0 = packets[0];
1006 ASSERT_TRUE(packet0.has_timestamp());
1007 EXPECT_EQ(packet0.timestamp(), 20u);
1008 ASSERT_TRUE(packet0.has_frame_timeline_event());
1009
1010 const auto& event0 = packet0.frame_timeline_event();
1011 ASSERT_TRUE(event0.has_actual_display_frame_start());
1012 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1013 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1014
1015 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1016 const auto& packet1 = packets[1];
1017 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001018 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001019 ASSERT_TRUE(packet1.has_frame_timeline_event());
1020
1021 const auto& event1 = packet1.frame_timeline_event();
1022 ASSERT_TRUE(event1.has_frame_end());
1023 const auto& actualDisplayFrameEnd = event1.frame_end();
1024 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1025}
1026
Adithya Srinivasan01189672020-10-20 14:23:05 -07001027TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1028 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001029 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001030 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -07001031 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1032 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1033
1034 tracingSession->StartBlocking();
1035 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1036 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001037
1038 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001039 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001040 sUidOne, sLayerIdOne, sLayerNameOne,
1041 sLayerNameOne);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001042 auto surfaceFrame2 =
1043 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001044 sUidOne, sLayerIdOne, sLayerNameOne,
1045 sLayerNameOne);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001046 surfaceFrame1->setActualQueueTime(10);
1047 surfaceFrame1->setDropTime(15);
1048
1049 surfaceFrame2->setActualQueueTime(15);
1050 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001051
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001052 // First 2 cookies will be used by the DisplayFrame
1053 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1054
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001055 auto protoDroppedSurfaceFrameExpectedStart =
1056 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1057 displayFrameToken1, sPidOne, sLayerNameOne);
1058 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1059 auto protoDroppedSurfaceFrameActualStart =
1060 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1061 displayFrameToken1, sPidOne, sLayerNameOne,
1062 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001063 FrameTimelineEvent::JANK_NONE,
1064 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001065 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001066
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001067 auto protoPresentedSurfaceFrameExpectedStart =
1068 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1069 displayFrameToken1, sPidOne, sLayerNameOne);
1070 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1071 auto protoPresentedSurfaceFrameActualStart =
1072 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1073 displayFrameToken1, sPidOne, sLayerNameOne,
1074 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001075 FrameTimelineEvent::JANK_NONE,
1076 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001077 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001078
1079 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -08001080 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001081 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1082 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001083 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001084 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001085 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001086 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001087
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001088 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001089 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001090 tracingSession->StopBlocking();
1091
1092 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001093 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1094 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001095
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001096 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001097 const auto& packet4 = packets[4];
1098 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001099 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001100 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001101
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001102 const auto& event4 = packet4.frame_timeline_event();
1103 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001104 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1105 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001106
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001107 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001108 const auto& packet5 = packets[5];
1109 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001110 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001111 ASSERT_TRUE(packet5.has_frame_timeline_event());
1112
1113 const auto& event5 = packet5.frame_timeline_event();
1114 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001115 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1116 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001117
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001118 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001119 const auto& packet6 = packets[6];
1120 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001121 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001122 ASSERT_TRUE(packet6.has_frame_timeline_event());
1123
1124 const auto& event6 = packet6.frame_timeline_event();
1125 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001126 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1127 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001128
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001129 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001130 const auto& packet7 = packets[7];
1131 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001132 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001133 ASSERT_TRUE(packet7.has_frame_timeline_event());
1134
1135 const auto& event7 = packet7.frame_timeline_event();
1136 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001137 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1138 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1139
1140 // Packet - 8 : ExpectedSurfaceFrameStart2
1141 const auto& packet8 = packets[8];
1142 ASSERT_TRUE(packet8.has_timestamp());
1143 EXPECT_EQ(packet8.timestamp(), 10u);
1144 ASSERT_TRUE(packet8.has_frame_timeline_event());
1145
1146 const auto& event8 = packet8.frame_timeline_event();
1147 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1148 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1149 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1150
1151 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1152 const auto& packet9 = packets[9];
1153 ASSERT_TRUE(packet9.has_timestamp());
1154 EXPECT_EQ(packet9.timestamp(), 25u);
1155 ASSERT_TRUE(packet9.has_frame_timeline_event());
1156
1157 const auto& event9 = packet9.frame_timeline_event();
1158 ASSERT_TRUE(event9.has_frame_end());
1159 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1160 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1161
1162 // Packet - 10 : ActualSurfaceFrameStart2
1163 const auto& packet10 = packets[10];
1164 ASSERT_TRUE(packet10.has_timestamp());
1165 EXPECT_EQ(packet10.timestamp(), 10u);
1166 ASSERT_TRUE(packet10.has_frame_timeline_event());
1167
1168 const auto& event10 = packet10.frame_timeline_event();
1169 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1170 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1171 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1172
1173 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1174 const auto& packet11 = packets[11];
1175 ASSERT_TRUE(packet11.has_timestamp());
1176 EXPECT_EQ(packet11.timestamp(), 20u);
1177 ASSERT_TRUE(packet11.has_frame_timeline_event());
1178
1179 const auto& event11 = packet11.frame_timeline_event();
1180 ASSERT_TRUE(event11.has_frame_end());
1181 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1182 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1183}
1184
1185TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1186 auto tracingSession = getTracingSessionForTest();
1187 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1188
1189 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001190 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1191 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1192 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001193 int64_t surfaceFrameToken =
1194 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1195
1196 // Flush the token so that it would expire
1197 flushTokens(systemTime() + maxTokenRetentionTime);
1198 auto surfaceFrame1 =
1199 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0},
Alec Mouriadebf5c2021-01-05 12:57:36 -08001200 sPidOne, sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001201 sLayerNameOne);
1202 surfaceFrame1->setActualQueueTime(appEndTime);
1203 surfaceFrame1->setAcquireFenceTime(appEndTime);
1204
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001205 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1206 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1207 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001208 int64_t displayFrameToken =
1209 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1210
1211 // First 2 cookies will be used by the DisplayFrame
1212 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1213
1214 auto protoActualSurfaceFrameStart =
1215 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1216 displayFrameToken, sPidOne, sLayerNameOne,
1217 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001218 false, FrameTimelineEvent::JANK_UNKNOWN,
1219 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001220 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1221
1222 // Set up the display frame
1223 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1224 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1225 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1226 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1227 presentFence1->signalForTest(sfPresentTime);
1228
1229 addEmptyDisplayFrame();
1230 flushTrace();
1231 tracingSession->StopBlocking();
1232
1233 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1234 // Display Frame 4 packets + SurfaceFrame 2 packets
1235 ASSERT_EQ(packets.size(), 6u);
1236
1237 // Packet - 4 : ActualSurfaceFrameStart
1238 const auto& packet4 = packets[4];
1239 ASSERT_TRUE(packet4.has_timestamp());
1240 EXPECT_EQ(packet4.timestamp(),
1241 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1242 ASSERT_TRUE(packet4.has_frame_timeline_event());
1243
1244 const auto& event4 = packet4.frame_timeline_event();
1245 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1246 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1247 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1248
1249 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1250 const auto& packet5 = packets[5];
1251 ASSERT_TRUE(packet5.has_timestamp());
1252 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1253 ASSERT_TRUE(packet5.has_frame_timeline_event());
1254
1255 const auto& event5 = packet5.frame_timeline_event();
1256 ASSERT_TRUE(event5.has_frame_end());
1257 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001258 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001259}
1260
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001261// Tests for Jank classification
1262TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001263 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001264 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001265 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1266 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001267 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001268 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001269 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001270 sUidOne, sLayerIdOne, sLayerNameOne,
1271 sLayerNameOne);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001272 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001273 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1274 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1275 mFrameTimeline->setSfPresent(26, presentFence1);
1276 auto displayFrame = getDisplayFrame(0);
1277 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1278 presentFence1->signalForTest(29);
1279
1280 // Fences haven't been flushed yet, so it should be 0
1281 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1282 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1283
1284 addEmptyDisplayFrame();
1285 displayFrame = getDisplayFrame(0);
1286
1287 // Fences have flushed, so the present timestamps should be updated
1288 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1289 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1290 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1291 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1292 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
1293}
1294
1295TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001296 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001297 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001298 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1299 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001300 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001301 mFrameTimeline->setSfPresent(26, presentFence1);
1302 auto displayFrame = getDisplayFrame(0);
1303 presentFence1->signalForTest(30);
1304
1305 // Fences for the first frame haven't been flushed yet, so it should be 0
1306 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1307
1308 // Trigger a flush by finalizing the next DisplayFrame
1309 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001310 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001311 mFrameTimeline->setSfPresent(56, presentFence2);
1312 displayFrame = getDisplayFrame(0);
1313
1314 // Fences for the first frame have flushed, so the present timestamps should be updated
1315 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1316 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1317 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1318 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1319
1320 // Fences for the second frame haven't been flushed yet, so it should be 0
1321 auto displayFrame2 = getDisplayFrame(1);
1322 presentFence2->signalForTest(65);
1323 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001324 addEmptyDisplayFrame();
1325 displayFrame2 = getDisplayFrame(1);
1326
1327 // Fences for the second frame have flushed, so the present timestamps should be updated
1328 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1329 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1330 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1331 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1332}
1333
1334TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001335 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001336 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001337 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1338 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001339 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001340 mFrameTimeline->setSfPresent(26, presentFence1);
1341 auto displayFrame = getDisplayFrame(0);
1342 presentFence1->signalForTest(50);
1343
1344 // Fences for the first frame haven't been flushed yet, so it should be 0
1345 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1346
1347 // Trigger a flush by finalizing the next DisplayFrame
1348 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001349 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001350 mFrameTimeline->setSfPresent(56, presentFence2);
1351 displayFrame = getDisplayFrame(0);
1352
1353 // Fences for the first frame have flushed, so the present timestamps should be updated
1354 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1355 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1356 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1357 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1358
1359 // Fences for the second frame haven't been flushed yet, so it should be 0
1360 auto displayFrame2 = getDisplayFrame(1);
1361 presentFence2->signalForTest(75);
1362 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1363
1364 addEmptyDisplayFrame();
1365 displayFrame2 = getDisplayFrame(1);
1366
1367 // Fences for the second frame have flushed, so the present timestamps should be updated
1368 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1369 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1370 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1371 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1372}
1373
1374TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001375 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1376 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001377 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001378
1379 mFrameTimeline->setSfPresent(22, presentFence1);
1380 auto displayFrame = getDisplayFrame(0);
1381 presentFence1->signalForTest(28);
1382
1383 // Fences haven't been flushed yet, so it should be 0
1384 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1385
1386 addEmptyDisplayFrame();
1387 displayFrame = getDisplayFrame(0);
1388
1389 // Fences have flushed, so the present timestamps should be updated
1390 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1391 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1392 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1393 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1394}
1395
1396TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001397 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1398 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001399 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001400 mFrameTimeline->setSfPresent(36, presentFence1);
1401 auto displayFrame = getDisplayFrame(0);
1402 presentFence1->signalForTest(52);
1403
1404 // Fences haven't been flushed yet, so it should be 0
1405 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1406
1407 addEmptyDisplayFrame();
1408 displayFrame = getDisplayFrame(0);
1409
1410 // Fences have flushed, so the present timestamps should be updated
1411 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
1412 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1413 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1414 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1415}
1416
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001417TEST_F(FrameTimelineTest, jankClassification_displayFrameLateStartLateFinishLatePresent) {
1418 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1419 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1420 mFrameTimeline->setSfWakeUp(sfToken1, 26, Fps::fromPeriodNsecs(11));
1421 mFrameTimeline->setSfPresent(36, presentFence1);
1422 auto displayFrame = getDisplayFrame(0);
1423 presentFence1->signalForTest(52);
1424
1425 // Fences haven't been flushed yet, so it should be 0
1426 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1427
1428 addEmptyDisplayFrame();
1429 displayFrame = getDisplayFrame(0);
1430
1431 // Fences have flushed, so the present timestamps should be updated
1432 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
1433 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::LateStart);
1434 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1435 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1436 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1437}
1438
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001439TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001440 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001441 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001442 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1443 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001444 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1445 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1446 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001447 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001448 sUidOne, sLayerIdOne, sLayerNameOne,
1449 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001450 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001451 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001452 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1453 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001454 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001455 auto displayFrame1 = getDisplayFrame(0);
1456 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1457 presentFence1->signalForTest(30);
1458
1459 // Fences for the first frame haven't been flushed yet, so it should be 0
1460 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1461 auto actuals1 = presentedSurfaceFrame1.getActuals();
1462 EXPECT_EQ(actuals1.presentTime, 0);
1463
1464 // Trigger a flush by finalizing the next DisplayFrame
1465 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1466 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001467 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001468 sUidOne, sLayerIdOne, sLayerNameOne,
1469 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001470 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001471 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001472 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1473 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001474 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001475 auto displayFrame2 = getDisplayFrame(1);
1476 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1477
1478 // Fences for the first frame have flushed, so the present timestamps should be updated
1479 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1480 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1481 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1482 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1483
1484 actuals1 = presentedSurfaceFrame1.getActuals();
1485 EXPECT_EQ(actuals1.presentTime, 30);
1486 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1487 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1488 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1489
1490 // Fences for the second frame haven't been flushed yet, so it should be 0
1491 presentFence2->signalForTest(65);
1492 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1493 auto actuals2 = presentedSurfaceFrame2.getActuals();
1494 EXPECT_EQ(actuals2.presentTime, 0);
1495
Alec Mouri363faf02021-01-29 16:34:55 -08001496 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1497
1498 EXPECT_CALL(*mTimeStats,
1499 incrementJankyFrames(
1500 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
1501 sLayerNameOne, JankType::PredictionError, 0, 5,
1502 0}));
1503
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001504 addEmptyDisplayFrame();
1505
1506 // Fences for the second frame have flushed, so the present timestamps should be updated
1507 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1508 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1509 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1510 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1511
1512 actuals2 = presentedSurfaceFrame2.getActuals();
1513 EXPECT_EQ(actuals2.presentTime, 65);
1514 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1515 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1516 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1517}
1518
1519TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001520 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001521 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001522 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1523 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001524 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1525 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1526 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001527 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001528 sUidOne, sLayerIdOne, sLayerNameOne,
1529 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001530 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001531 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001532 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1533 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1534 mFrameTimeline->setSfPresent(26, presentFence1);
1535 auto displayFrame1 = getDisplayFrame(0);
1536 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1537 presentFence1->signalForTest(50);
1538
1539 // Fences for the first frame haven't been flushed yet, so it should be 0
1540 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1541 auto actuals1 = presentedSurfaceFrame1.getActuals();
1542 EXPECT_EQ(actuals1.presentTime, 0);
1543
1544 // Trigger a flush by finalizing the next DisplayFrame
1545 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1546 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001547 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001548 sUidOne, sLayerIdOne, sLayerNameOne,
1549 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001550 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001551 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001552 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1553 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001554 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001555 auto displayFrame2 = getDisplayFrame(1);
1556 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1557
1558 // Fences for the first frame have flushed, so the present timestamps should be updated
1559 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1560 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1561 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1562 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1563
1564 actuals1 = presentedSurfaceFrame1.getActuals();
1565 EXPECT_EQ(actuals1.presentTime, 50);
1566 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1567 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1568 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1569
1570 // Fences for the second frame haven't been flushed yet, so it should be 0
1571 presentFence2->signalForTest(86);
1572 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1573 auto actuals2 = presentedSurfaceFrame2.getActuals();
1574 EXPECT_EQ(actuals2.presentTime, 0);
1575
Alec Mouri363faf02021-01-29 16:34:55 -08001576 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1577
1578 EXPECT_CALL(*mTimeStats,
1579 incrementJankyFrames(
1580 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
1581 sLayerNameOne, JankType::PredictionError, 0, 5,
1582 0}));
1583
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001584 addEmptyDisplayFrame();
1585
1586 // Fences for the second frame have flushed, so the present timestamps should be updated
1587 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1588 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1589 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1590 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1591
1592 actuals2 = presentedSurfaceFrame2.getActuals();
1593 EXPECT_EQ(actuals2.presentTime, 86);
1594 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1595 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1596 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1597}
1598
1599TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001600 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08001601
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001602 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001603 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001604 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
1605 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001606 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001607 sUidOne, sLayerIdOne, sLayerNameOne,
1608 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001609 surfaceFrame1->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001610 mFrameTimeline->setSfWakeUp(sfToken1, 42, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001611 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1612 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1613 mFrameTimeline->setSfPresent(46, presentFence1);
1614 auto displayFrame1 = getDisplayFrame(0);
1615 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1616 presentFence1->signalForTest(50);
1617
1618 // Fences for the first frame haven't been flushed yet, so it should be 0
1619 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1620 auto actuals1 = presentedSurfaceFrame1.getActuals();
1621 EXPECT_EQ(actuals1.presentTime, 0);
1622
1623 addEmptyDisplayFrame();
1624
1625 // Fences for the first frame have flushed, so the present timestamps should be updated
1626 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1627 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1628 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1629 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1630
1631 actuals1 = presentedSurfaceFrame1.getActuals();
1632 EXPECT_EQ(actuals1.presentTime, 50);
1633 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1634 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1635 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
1636}
1637
1638TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
1639 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as
1640 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
1641 // jank to the SurfaceFrame.
1642
Alec Mouri363faf02021-01-29 16:34:55 -08001643 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001644 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001645 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
1646 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001647 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1648 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
1649 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001650 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001651 sUidOne, sLayerIdOne, sLayerNameOne,
1652 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001653 surfaceFrame1->setAcquireFenceTime(26);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001654 mFrameTimeline->setSfWakeUp(sfToken1, 32, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001655 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1656 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1657 mFrameTimeline->setSfPresent(36, presentFence1);
1658 auto displayFrame1 = getDisplayFrame(0);
1659 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1660 presentFence1->signalForTest(40);
1661
1662 // Fences for the first frame haven't been flushed yet, so it should be 0
1663 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1664 auto actuals1 = presentedSurfaceFrame1.getActuals();
1665 EXPECT_EQ(actuals1.presentTime, 0);
1666
1667 // Trigger a flush by finalizing the next DisplayFrame
1668 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1669 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001670 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001671 sUidOne, sLayerIdOne, sLayerNameOne,
1672 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001673 surfaceFrame2->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001674 mFrameTimeline->setSfWakeUp(sfToken2, 43, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001675 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1676 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1677 mFrameTimeline->setSfPresent(56, presentFence2);
1678 auto displayFrame2 = getDisplayFrame(1);
1679 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1680
1681 // Fences for the first frame have flushed, so the present timestamps should be updated
1682 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
1683 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1684 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1685 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1686
1687 actuals1 = presentedSurfaceFrame1.getActuals();
1688 EXPECT_EQ(actuals1.presentTime, 40);
1689 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1690 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1691 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1692
1693 // Fences for the second frame haven't been flushed yet, so it should be 0
1694 presentFence2->signalForTest(60);
1695 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1696 auto actuals2 = presentedSurfaceFrame2.getActuals();
1697 EXPECT_EQ(actuals2.presentTime, 0);
1698
1699 addEmptyDisplayFrame();
1700
1701 // Fences for the second frame have flushed, so the present timestamps should be updated
1702 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
1703 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1704 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1705 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1706
1707 actuals2 = presentedSurfaceFrame2.getActuals();
1708 EXPECT_EQ(actuals2.presentTime, 60);
1709 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1710 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1711 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1712}
1713
1714TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001715 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001716 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001717 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1718 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
1719 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
1720
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001721 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
1722 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001723 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001724 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001725 sUidOne, sLayerIdOne, sLayerNameOne,
1726 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001727 surfaceFrame1->setAcquireFenceTime(50);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001728 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001729 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1730 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1731 mFrameTimeline->setSfPresent(56, presentFence1);
1732 auto displayFrame1 = getDisplayFrame(0);
1733 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1734 presentFence1->signalForTest(60);
1735
1736 // Fences for the first frame haven't been flushed yet, so it should be 0
1737 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1738 auto actuals1 = presentedSurfaceFrame1.getActuals();
1739 EXPECT_EQ(actuals1.presentTime, 0);
1740
1741 // Trigger a flush by finalizing the next DisplayFrame
1742 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1743 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001744 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001745 sUidOne, sLayerIdOne, sLayerNameOne,
1746 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001747 surfaceFrame2->setAcquireFenceTime(84);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001748 mFrameTimeline->setSfWakeUp(sfToken2, 112, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001749 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
1750 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1751 mFrameTimeline->setSfPresent(116, presentFence2);
1752 auto displayFrame2 = getDisplayFrame(1);
1753 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1754 presentFence2->signalForTest(120);
1755
1756 // Fences for the first frame have flushed, so the present timestamps should be updated
1757 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
1758 actuals1 = presentedSurfaceFrame1.getActuals();
1759 EXPECT_EQ(actuals1.endTime, 50);
1760 EXPECT_EQ(actuals1.presentTime, 60);
1761
1762 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1763 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1764 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1765
1766 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1767 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1768 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1769
1770 // Fences for the second frame haven't been flushed yet, so it should be 0
1771 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1772 auto actuals2 = presentedSurfaceFrame2.getActuals();
1773 EXPECT_EQ(actuals2.presentTime, 0);
1774
1775 addEmptyDisplayFrame();
1776
1777 // Fences for the second frame have flushed, so the present timestamps should be updated
1778 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1779 actuals2 = presentedSurfaceFrame2.getActuals();
1780 EXPECT_EQ(actuals2.presentTime, 120);
1781
1782 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1783 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1784 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
1785
1786 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1787 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1788 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
1789 JankType::AppDeadlineMissed | JankType::BufferStuffing);
1790}
Alec Mouriadebf5c2021-01-05 12:57:36 -08001791
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001792TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
1793 // Layer specific increment
1794 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
1795 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1796 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
1797 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
1798
1799 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
1800 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1801 auto surfaceFrame1 =
1802 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1803 sUidOne, sLayerIdOne, sLayerNameOne,
1804 sLayerNameOne);
1805 surfaceFrame1->setAcquireFenceTime(50);
1806 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
1807 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1808 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1809 mFrameTimeline->setSfPresent(56, presentFence1);
1810 auto displayFrame1 = getDisplayFrame(0);
1811 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1812 presentFence1->signalForTest(60);
1813
1814 // Fences for the first frame haven't been flushed yet, so it should be 0
1815 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1816 auto actuals1 = presentedSurfaceFrame1.getActuals();
1817 EXPECT_EQ(actuals1.presentTime, 0);
1818
1819 // Trigger a flush by finalizing the next DisplayFrame
1820 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1821 auto surfaceFrame2 =
1822 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1823 sUidOne, sLayerIdOne, sLayerNameOne,
1824 sLayerNameOne);
1825 surfaceFrame2->setAcquireFenceTime(80);
1826 mFrameTimeline->setSfWakeUp(sfToken2, 82, Fps::fromPeriodNsecs(30));
1827 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
1828 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
1829 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1830 mFrameTimeline->setSfPresent(86, presentFence2);
1831 auto displayFrame2 = getDisplayFrame(1);
1832 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1833 presentFence2->signalForTest(90);
1834
1835 // Fences for the first frame have flushed, so the present timestamps should be updated
1836 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
1837 actuals1 = presentedSurfaceFrame1.getActuals();
1838 EXPECT_EQ(actuals1.endTime, 50);
1839 EXPECT_EQ(actuals1.presentTime, 60);
1840
1841 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1842 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1843 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1844
1845 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1846 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1847 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1848
1849 // Fences for the second frame haven't been flushed yet, so it should be 0
1850 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1851 auto actuals2 = presentedSurfaceFrame2.getActuals();
1852 EXPECT_EQ(actuals2.presentTime, 0);
1853
1854 addEmptyDisplayFrame();
1855
1856 // Fences for the second frame have flushed, so the present timestamps should be updated
1857 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
1858 actuals2 = presentedSurfaceFrame2.getActuals();
1859 EXPECT_EQ(actuals2.presentTime, 90);
1860
1861 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1862 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1863 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
1864
1865 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1866 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1867 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
1868}
1869
Alec Mouriadebf5c2021-01-05 12:57:36 -08001870TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
1871 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
1872}
1873
1874TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001875 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08001876
1877 auto surfaceFrame1 =
1878 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1879 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1880 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1881 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1882 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1883 presentFence1->signalForTest(oneHundredMs);
1884 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
1885
1886 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
1887}
1888
1889TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001890 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
1891 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08001892 auto surfaceFrame1 =
1893 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1894 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1895 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1896 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1897 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1898 presentFence1->signalForTest(oneHundredMs);
1899 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
1900
1901 auto surfaceFrame2 =
1902 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1903 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1904 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1905 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1906 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1907 presentFence2->signalForTest(twoHundredMs);
1908 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
1909
1910 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
1911}
1912
1913TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001914 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
1915 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08001916 auto surfaceFrame1 =
1917 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1918 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1919 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1920 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1921 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1922 presentFence1->signalForTest(oneHundredMs);
1923 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
1924
1925 auto surfaceFrame2 =
1926 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1927 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo);
1928 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1929 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1930 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1931 presentFence2->signalForTest(twoHundredMs);
1932 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
1933
1934 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
1935}
1936
1937TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001938 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
1939 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08001940 auto surfaceFrame1 =
1941 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1942 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1943 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1944 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1945 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1946 presentFence1->signalForTest(oneHundredMs);
1947 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
1948
1949 auto surfaceFrame2 =
1950 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1951 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo);
1952 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1953 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1954 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1955 presentFence2->signalForTest(twoHundredMs);
1956 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
1957
1958 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
1959}
1960
1961TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001962 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
1963 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
1964 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
1965 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
1966 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08001967 auto surfaceFrame1 =
1968 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1969 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1970 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1971 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1972 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1973 presentFence1->signalForTest(oneHundredMs);
1974 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
1975
1976 auto surfaceFrame2 =
1977 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1978 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1979 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1980 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1981 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1982 presentFence2->signalForTest(twoHundredMs);
1983 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
1984
1985 auto surfaceFrame3 =
1986 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1987 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo);
1988 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1989 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
1990 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
1991 presentFence3->signalForTest(threeHundredMs);
1992 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
1993
1994 auto surfaceFrame4 =
1995 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1996 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1997 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1998 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
1999 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2000 presentFence4->signalForTest(fiveHundredMs);
2001 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2002
2003 auto surfaceFrame5 =
2004 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
2005 sLayerIdOne, sLayerNameOne, sLayerNameOne);
2006 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2007 // Dropped frames will be excluded from fps computation
2008 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2009 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2010 presentFence5->signalForTest(sixHundredMs);
2011 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2012
2013 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2014}
2015
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002016} // namespace android::frametimeline