blob: f2cb9513f01104abde706b79d887b214d10e2b5b [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 Srinivasan01189672020-10-20 14:23:05 -0700606/*
607 * Tracing Tests
608 *
609 * Trace packets are flushed all the way only when the next packet is traced.
610 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
611 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
612 * will have additional empty frames created for this reason.
613 */
614TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
615 auto tracingSession = getTracingSessionForTest();
616 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700617 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000618 auto surfaceFrame1 =
619 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800620 sLayerIdOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700621
622 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800623 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800624 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
625 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700626 mFrameTimeline->setSfPresent(25, presentFence1);
627 presentFence1->signalForTest(30);
628
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000629 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700630
631 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000632 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700633}
634
635TEST_F(FrameTimelineTest, tracing_sanityTest) {
636 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800637 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800638 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700639 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700640
641 tracingSession->StartBlocking();
642 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
643 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000644 auto surfaceFrame1 =
645 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800646 sLayerIdOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700647
648 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800649 mFrameTimeline->setSfWakeUp(token2, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800650 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
651 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700652 mFrameTimeline->setSfPresent(25, presentFence1);
653 presentFence1->signalForTest(30);
654
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000655 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000656 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700657 tracingSession->StopBlocking();
658
659 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000660 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000661 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700662}
663
664TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
665 auto tracingSession = getTracingSessionForTest();
666 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700667
668 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700669
670 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800671 mFrameTimeline->setSfWakeUp(-1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700672 mFrameTimeline->setSfPresent(25, presentFence1);
673 presentFence1->signalForTest(30);
674
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000675 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000676 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700677 tracingSession->StopBlocking();
678
679 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000680 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700681}
682
683TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
684 auto tracingSession = getTracingSessionForTest();
685 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700686
687 tracingSession->StartBlocking();
688 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -0800689 auto surfaceFrame1 =
690 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
691 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700692
693 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800694 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800695 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
696 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700697 mFrameTimeline->setSfPresent(25, presentFence1);
698 presentFence1->signalForTest(30);
699
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000700 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000701 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700702 tracingSession->StopBlocking();
703
704 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000705 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
706 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000707 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700708}
709
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000710ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
711 pid_t pid) {
712 ProtoExpectedDisplayFrameStart proto;
713 proto.set_cookie(cookie);
714 proto.set_token(token);
715 proto.set_pid(pid);
716 return proto;
717}
718
719ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
720 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000721 bool gpuComposition, ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000722 ProtoActualDisplayFrameStart proto;
723 proto.set_cookie(cookie);
724 proto.set_token(token);
725 proto.set_pid(pid);
726 proto.set_present_type(presentType);
727 proto.set_on_time_finish(onTimeFinish);
728 proto.set_gpu_composition(gpuComposition);
729 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000730 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000731 return proto;
732}
733
734ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
735 int64_t displayFrameToken,
736 pid_t pid,
737 std::string layerName) {
738 ProtoExpectedSurfaceFrameStart proto;
739 proto.set_cookie(cookie);
740 proto.set_token(token);
741 proto.set_display_frame_token(displayFrameToken);
742 proto.set_pid(pid);
743 proto.set_layer_name(layerName);
744 return proto;
745}
746
747ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
748 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
749 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000750 ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000751 ProtoActualSurfaceFrameStart proto;
752 proto.set_cookie(cookie);
753 proto.set_token(token);
754 proto.set_display_frame_token(displayFrameToken);
755 proto.set_pid(pid);
756 proto.set_layer_name(layerName);
757 proto.set_present_type(presentType);
758 proto.set_on_time_finish(onTimeFinish);
759 proto.set_gpu_composition(gpuComposition);
760 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000761 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000762 return proto;
763}
764
765ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
766 ProtoFrameEnd proto;
767 proto.set_cookie(cookie);
768 return proto;
769}
770
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000771void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
772 const ProtoExpectedDisplayFrameStart& source) {
773 ASSERT_TRUE(received.has_cookie());
774 EXPECT_EQ(received.cookie(), source.cookie());
775
Adithya Srinivasan01189672020-10-20 14:23:05 -0700776 ASSERT_TRUE(received.has_token());
777 EXPECT_EQ(received.token(), source.token());
778
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000779 ASSERT_TRUE(received.has_pid());
780 EXPECT_EQ(received.pid(), source.pid());
781}
782
783void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
784 const ProtoActualDisplayFrameStart& source) {
785 ASSERT_TRUE(received.has_cookie());
786 EXPECT_EQ(received.cookie(), source.cookie());
787
788 ASSERT_TRUE(received.has_token());
789 EXPECT_EQ(received.token(), source.token());
790
791 ASSERT_TRUE(received.has_pid());
792 EXPECT_EQ(received.pid(), source.pid());
793
Adithya Srinivasan01189672020-10-20 14:23:05 -0700794 ASSERT_TRUE(received.has_present_type());
795 EXPECT_EQ(received.present_type(), source.present_type());
796 ASSERT_TRUE(received.has_on_time_finish());
797 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
798 ASSERT_TRUE(received.has_gpu_composition());
799 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
800 ASSERT_TRUE(received.has_jank_type());
801 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000802 ASSERT_TRUE(received.has_prediction_type());
803 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700804}
805
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000806void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
807 const ProtoExpectedSurfaceFrameStart& source) {
808 ASSERT_TRUE(received.has_cookie());
809 EXPECT_EQ(received.cookie(), source.cookie());
810
Adithya Srinivasan01189672020-10-20 14:23:05 -0700811 ASSERT_TRUE(received.has_token());
812 EXPECT_EQ(received.token(), source.token());
813
814 ASSERT_TRUE(received.has_display_frame_token());
815 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
816
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000817 ASSERT_TRUE(received.has_pid());
818 EXPECT_EQ(received.pid(), source.pid());
819
820 ASSERT_TRUE(received.has_layer_name());
821 EXPECT_EQ(received.layer_name(), source.layer_name());
822}
823
824void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
825 const ProtoActualSurfaceFrameStart& source) {
826 ASSERT_TRUE(received.has_cookie());
827 EXPECT_EQ(received.cookie(), source.cookie());
828
829 ASSERT_TRUE(received.has_token());
830 EXPECT_EQ(received.token(), source.token());
831
832 ASSERT_TRUE(received.has_display_frame_token());
833 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
834
835 ASSERT_TRUE(received.has_pid());
836 EXPECT_EQ(received.pid(), source.pid());
837
838 ASSERT_TRUE(received.has_layer_name());
839 EXPECT_EQ(received.layer_name(), source.layer_name());
840
Adithya Srinivasan01189672020-10-20 14:23:05 -0700841 ASSERT_TRUE(received.has_present_type());
842 EXPECT_EQ(received.present_type(), source.present_type());
843 ASSERT_TRUE(received.has_on_time_finish());
844 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
845 ASSERT_TRUE(received.has_gpu_composition());
846 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
847 ASSERT_TRUE(received.has_jank_type());
848 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000849 ASSERT_TRUE(received.has_prediction_type());
850 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000851}
Adithya Srinivasan01189672020-10-20 14:23:05 -0700852
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000853void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
854 ASSERT_TRUE(received.has_cookie());
855 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700856}
857
858TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
859 auto tracingSession = getTracingSessionForTest();
860 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700861
862 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000863 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -0700864
865 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800866 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700867 mFrameTimeline->setSfPresent(26, presentFence1);
868 presentFence1->signalForTest(31);
869
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000870 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000871 auto protoExpectedDisplayFrameStart =
872 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
873 kSurfaceFlingerPid);
874 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
875 auto protoActualDisplayFrameStart =
876 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
877 kSurfaceFlingerPid,
878 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000879 FrameTimelineEvent::JANK_NONE,
880 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000881 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000882
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000883 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000884 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700885 tracingSession->StopBlocking();
886
887 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000888 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700889
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000890 // Packet - 0 : ExpectedDisplayFrameStart
891 const auto& packet0 = packets[0];
892 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000893 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000894 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700895
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000896 const auto& event0 = packet0.frame_timeline_event();
897 ASSERT_TRUE(event0.has_expected_display_frame_start());
898 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
899 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
900
901 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
902 const auto& packet1 = packets[1];
903 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000904 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000905 ASSERT_TRUE(packet1.has_frame_timeline_event());
906
907 const auto& event1 = packet1.frame_timeline_event();
908 ASSERT_TRUE(event1.has_frame_end());
909 const auto& expectedDisplayFrameEnd = event1.frame_end();
910 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
911
912 // Packet - 2 : ActualDisplayFrameStart
913 const auto& packet2 = packets[2];
914 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000915 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000916 ASSERT_TRUE(packet2.has_frame_timeline_event());
917
918 const auto& event2 = packet2.frame_timeline_event();
919 ASSERT_TRUE(event2.has_actual_display_frame_start());
920 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
921 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
922
923 // Packet - 3 : FrameEnd (ActualDisplayFrame)
924 const auto& packet3 = packets[3];
925 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +0000926 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000927 ASSERT_TRUE(packet3.has_frame_timeline_event());
928
929 const auto& event3 = packet3.frame_timeline_event();
930 ASSERT_TRUE(event3.has_frame_end());
931 const auto& actualDisplayFrameEnd = event3.frame_end();
932 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700933}
934
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000935TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
936 auto tracingSession = getTracingSessionForTest();
937 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
938
939 tracingSession->StartBlocking();
940 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
941 // Flush the token so that it would expire
942 flushTokens(systemTime() + maxTokenRetentionTime);
943
944 // Set up the display frame
945 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
946 mFrameTimeline->setSfPresent(26, presentFence1);
947 presentFence1->signalForTest(31);
948
949 int64_t traceCookie = snoopCurrentTraceCookie();
950
951 auto protoActualDisplayFrameStart =
952 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
953 kSurfaceFlingerPid,
954 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000955 false, FrameTimelineEvent::JANK_UNKNOWN,
956 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000957 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
958
959 addEmptyDisplayFrame();
960 flushTrace();
961 tracingSession->StopBlocking();
962
963 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
964 // Only actual timeline packets should be in the trace
965 EXPECT_EQ(packets.size(), 2u);
966
967 // Packet - 0 : ActualDisplayFrameStart
968 const auto& packet0 = packets[0];
969 ASSERT_TRUE(packet0.has_timestamp());
970 EXPECT_EQ(packet0.timestamp(), 20u);
971 ASSERT_TRUE(packet0.has_frame_timeline_event());
972
973 const auto& event0 = packet0.frame_timeline_event();
974 ASSERT_TRUE(event0.has_actual_display_frame_start());
975 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
976 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
977
978 // Packet - 1 : FrameEnd (ActualDisplayFrame)
979 const auto& packet1 = packets[1];
980 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +0000981 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000982 ASSERT_TRUE(packet1.has_frame_timeline_event());
983
984 const auto& event1 = packet1.frame_timeline_event();
985 ASSERT_TRUE(event1.has_frame_end());
986 const auto& actualDisplayFrameEnd = event1.frame_end();
987 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
988}
989
Adithya Srinivasan01189672020-10-20 14:23:05 -0700990TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
991 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800992 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800993 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700994 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
995 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
996
997 tracingSession->StartBlocking();
998 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
999 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001000
1001 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001002 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001003 sUidOne, sLayerIdOne, sLayerNameOne,
1004 sLayerNameOne);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001005 auto surfaceFrame2 =
1006 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001007 sUidOne, sLayerIdOne, sLayerNameOne,
1008 sLayerNameOne);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001009 surfaceFrame1->setActualQueueTime(10);
1010 surfaceFrame1->setDropTime(15);
1011
1012 surfaceFrame2->setActualQueueTime(15);
1013 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001014
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001015 // First 2 cookies will be used by the DisplayFrame
1016 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1017
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001018 auto protoDroppedSurfaceFrameExpectedStart =
1019 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1020 displayFrameToken1, sPidOne, sLayerNameOne);
1021 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1022 auto protoDroppedSurfaceFrameActualStart =
1023 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1024 displayFrameToken1, sPidOne, sLayerNameOne,
1025 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001026 FrameTimelineEvent::JANK_NONE,
1027 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001028 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001029
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001030 auto protoPresentedSurfaceFrameExpectedStart =
1031 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1032 displayFrameToken1, sPidOne, sLayerNameOne);
1033 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1034 auto protoPresentedSurfaceFrameActualStart =
1035 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1036 displayFrameToken1, sPidOne, sLayerNameOne,
1037 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001038 FrameTimelineEvent::JANK_NONE,
1039 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001040 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001041
1042 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -08001043 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001044 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1045 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001046 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001047 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001048 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001049 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001050
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001051 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001052 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001053 tracingSession->StopBlocking();
1054
1055 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001056 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1057 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001058
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001059 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001060 const auto& packet4 = packets[4];
1061 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001062 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001063 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001064
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001065 const auto& event4 = packet4.frame_timeline_event();
1066 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001067 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1068 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001069
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001070 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001071 const auto& packet5 = packets[5];
1072 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001073 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001074 ASSERT_TRUE(packet5.has_frame_timeline_event());
1075
1076 const auto& event5 = packet5.frame_timeline_event();
1077 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001078 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1079 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001080
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001081 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001082 const auto& packet6 = packets[6];
1083 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001084 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001085 ASSERT_TRUE(packet6.has_frame_timeline_event());
1086
1087 const auto& event6 = packet6.frame_timeline_event();
1088 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001089 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1090 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001091
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001092 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001093 const auto& packet7 = packets[7];
1094 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001095 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001096 ASSERT_TRUE(packet7.has_frame_timeline_event());
1097
1098 const auto& event7 = packet7.frame_timeline_event();
1099 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001100 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1101 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1102
1103 // Packet - 8 : ExpectedSurfaceFrameStart2
1104 const auto& packet8 = packets[8];
1105 ASSERT_TRUE(packet8.has_timestamp());
1106 EXPECT_EQ(packet8.timestamp(), 10u);
1107 ASSERT_TRUE(packet8.has_frame_timeline_event());
1108
1109 const auto& event8 = packet8.frame_timeline_event();
1110 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1111 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1112 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1113
1114 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1115 const auto& packet9 = packets[9];
1116 ASSERT_TRUE(packet9.has_timestamp());
1117 EXPECT_EQ(packet9.timestamp(), 25u);
1118 ASSERT_TRUE(packet9.has_frame_timeline_event());
1119
1120 const auto& event9 = packet9.frame_timeline_event();
1121 ASSERT_TRUE(event9.has_frame_end());
1122 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1123 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1124
1125 // Packet - 10 : ActualSurfaceFrameStart2
1126 const auto& packet10 = packets[10];
1127 ASSERT_TRUE(packet10.has_timestamp());
1128 EXPECT_EQ(packet10.timestamp(), 10u);
1129 ASSERT_TRUE(packet10.has_frame_timeline_event());
1130
1131 const auto& event10 = packet10.frame_timeline_event();
1132 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1133 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1134 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1135
1136 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1137 const auto& packet11 = packets[11];
1138 ASSERT_TRUE(packet11.has_timestamp());
1139 EXPECT_EQ(packet11.timestamp(), 20u);
1140 ASSERT_TRUE(packet11.has_frame_timeline_event());
1141
1142 const auto& event11 = packet11.frame_timeline_event();
1143 ASSERT_TRUE(event11.has_frame_end());
1144 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1145 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1146}
1147
1148TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1149 auto tracingSession = getTracingSessionForTest();
1150 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1151
1152 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001153 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1154 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1155 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001156 int64_t surfaceFrameToken =
1157 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1158
1159 // Flush the token so that it would expire
1160 flushTokens(systemTime() + maxTokenRetentionTime);
1161 auto surfaceFrame1 =
1162 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0},
Alec Mouriadebf5c2021-01-05 12:57:36 -08001163 sPidOne, sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001164 sLayerNameOne);
1165 surfaceFrame1->setActualQueueTime(appEndTime);
1166 surfaceFrame1->setAcquireFenceTime(appEndTime);
1167
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001168 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1169 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1170 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001171 int64_t displayFrameToken =
1172 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1173
1174 // First 2 cookies will be used by the DisplayFrame
1175 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1176
1177 auto protoActualSurfaceFrameStart =
1178 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1179 displayFrameToken, sPidOne, sLayerNameOne,
1180 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001181 false, FrameTimelineEvent::JANK_UNKNOWN,
1182 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001183 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1184
1185 // Set up the display frame
1186 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1187 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1188 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1189 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1190 presentFence1->signalForTest(sfPresentTime);
1191
1192 addEmptyDisplayFrame();
1193 flushTrace();
1194 tracingSession->StopBlocking();
1195
1196 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1197 // Display Frame 4 packets + SurfaceFrame 2 packets
1198 ASSERT_EQ(packets.size(), 6u);
1199
1200 // Packet - 4 : ActualSurfaceFrameStart
1201 const auto& packet4 = packets[4];
1202 ASSERT_TRUE(packet4.has_timestamp());
1203 EXPECT_EQ(packet4.timestamp(),
1204 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1205 ASSERT_TRUE(packet4.has_frame_timeline_event());
1206
1207 const auto& event4 = packet4.frame_timeline_event();
1208 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1209 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1210 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1211
1212 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1213 const auto& packet5 = packets[5];
1214 ASSERT_TRUE(packet5.has_timestamp());
1215 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1216 ASSERT_TRUE(packet5.has_frame_timeline_event());
1217
1218 const auto& event5 = packet5.frame_timeline_event();
1219 ASSERT_TRUE(event5.has_frame_end());
1220 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001221 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001222}
1223
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001224// Tests for Jank classification
1225TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001226 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001227 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001228 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1229 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001230 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001231 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001232 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001233 sUidOne, sLayerIdOne, sLayerNameOne,
1234 sLayerNameOne);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001235 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001236 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1237 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1238 mFrameTimeline->setSfPresent(26, presentFence1);
1239 auto displayFrame = getDisplayFrame(0);
1240 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1241 presentFence1->signalForTest(29);
1242
1243 // Fences haven't been flushed yet, so it should be 0
1244 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1245 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1246
1247 addEmptyDisplayFrame();
1248 displayFrame = getDisplayFrame(0);
1249
1250 // Fences have flushed, so the present timestamps should be updated
1251 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1252 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1253 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1254 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1255 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
1256}
1257
1258TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001259 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001260 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001261 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1262 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001263 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001264 mFrameTimeline->setSfPresent(26, presentFence1);
1265 auto displayFrame = getDisplayFrame(0);
1266 presentFence1->signalForTest(30);
1267
1268 // Fences for the first frame haven't been flushed yet, so it should be 0
1269 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1270
1271 // Trigger a flush by finalizing the next DisplayFrame
1272 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001273 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001274 mFrameTimeline->setSfPresent(56, presentFence2);
1275 displayFrame = getDisplayFrame(0);
1276
1277 // Fences for the first frame have flushed, so the present timestamps should be updated
1278 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1279 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1280 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1281 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1282
1283 // Fences for the second frame haven't been flushed yet, so it should be 0
1284 auto displayFrame2 = getDisplayFrame(1);
1285 presentFence2->signalForTest(65);
1286 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001287 addEmptyDisplayFrame();
1288 displayFrame2 = getDisplayFrame(1);
1289
1290 // Fences for the second frame have flushed, so the present timestamps should be updated
1291 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1292 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1293 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1294 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1295}
1296
1297TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001298 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001299 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001300 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1301 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001302 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001303 mFrameTimeline->setSfPresent(26, presentFence1);
1304 auto displayFrame = getDisplayFrame(0);
1305 presentFence1->signalForTest(50);
1306
1307 // Fences for the first frame haven't been flushed yet, so it should be 0
1308 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1309
1310 // Trigger a flush by finalizing the next DisplayFrame
1311 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001312 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001313 mFrameTimeline->setSfPresent(56, presentFence2);
1314 displayFrame = getDisplayFrame(0);
1315
1316 // Fences for the first frame have flushed, so the present timestamps should be updated
1317 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1318 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1319 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1320 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1321
1322 // Fences for the second frame haven't been flushed yet, so it should be 0
1323 auto displayFrame2 = getDisplayFrame(1);
1324 presentFence2->signalForTest(75);
1325 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1326
1327 addEmptyDisplayFrame();
1328 displayFrame2 = getDisplayFrame(1);
1329
1330 // Fences for the second frame have flushed, so the present timestamps should be updated
1331 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1332 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1333 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1334 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1335}
1336
1337TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001338 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1339 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001340 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001341
1342 mFrameTimeline->setSfPresent(22, presentFence1);
1343 auto displayFrame = getDisplayFrame(0);
1344 presentFence1->signalForTest(28);
1345
1346 // Fences haven't been flushed yet, so it should be 0
1347 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1348
1349 addEmptyDisplayFrame();
1350 displayFrame = getDisplayFrame(0);
1351
1352 // Fences have flushed, so the present timestamps should be updated
1353 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1354 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1355 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1356 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1357}
1358
1359TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001360 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1361 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001362 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001363 mFrameTimeline->setSfPresent(36, presentFence1);
1364 auto displayFrame = getDisplayFrame(0);
1365 presentFence1->signalForTest(52);
1366
1367 // Fences haven't been flushed yet, so it should be 0
1368 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1369
1370 addEmptyDisplayFrame();
1371 displayFrame = getDisplayFrame(0);
1372
1373 // Fences have flushed, so the present timestamps should be updated
1374 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
1375 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1376 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1377 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1378}
1379
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001380TEST_F(FrameTimelineTest, jankClassification_displayFrameLateStartLateFinishLatePresent) {
1381 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1382 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1383 mFrameTimeline->setSfWakeUp(sfToken1, 26, Fps::fromPeriodNsecs(11));
1384 mFrameTimeline->setSfPresent(36, presentFence1);
1385 auto displayFrame = getDisplayFrame(0);
1386 presentFence1->signalForTest(52);
1387
1388 // Fences haven't been flushed yet, so it should be 0
1389 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1390
1391 addEmptyDisplayFrame();
1392 displayFrame = getDisplayFrame(0);
1393
1394 // Fences have flushed, so the present timestamps should be updated
1395 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
1396 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::LateStart);
1397 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1398 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1399 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1400}
1401
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001402TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001403 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001404 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001405 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1406 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001407 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1408 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1409 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001410 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001411 sUidOne, sLayerIdOne, sLayerNameOne,
1412 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001413 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001414 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001415 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1416 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001417 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001418 auto displayFrame1 = getDisplayFrame(0);
1419 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1420 presentFence1->signalForTest(30);
1421
1422 // Fences for the first frame haven't been flushed yet, so it should be 0
1423 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1424 auto actuals1 = presentedSurfaceFrame1.getActuals();
1425 EXPECT_EQ(actuals1.presentTime, 0);
1426
1427 // Trigger a flush by finalizing the next DisplayFrame
1428 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1429 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001430 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001431 sUidOne, sLayerIdOne, sLayerNameOne,
1432 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001433 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001434 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001435 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1436 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001437 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001438 auto displayFrame2 = getDisplayFrame(1);
1439 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1440
1441 // Fences for the first frame have flushed, so the present timestamps should be updated
1442 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1443 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1444 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1445 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1446
1447 actuals1 = presentedSurfaceFrame1.getActuals();
1448 EXPECT_EQ(actuals1.presentTime, 30);
1449 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1450 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1451 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1452
1453 // Fences for the second frame haven't been flushed yet, so it should be 0
1454 presentFence2->signalForTest(65);
1455 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1456 auto actuals2 = presentedSurfaceFrame2.getActuals();
1457 EXPECT_EQ(actuals2.presentTime, 0);
1458
Alec Mouri363faf02021-01-29 16:34:55 -08001459 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1460
1461 EXPECT_CALL(*mTimeStats,
1462 incrementJankyFrames(
1463 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
1464 sLayerNameOne, JankType::PredictionError, 0, 5,
1465 0}));
1466
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001467 addEmptyDisplayFrame();
1468
1469 // Fences for the second frame have flushed, so the present timestamps should be updated
1470 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1471 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1472 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1473 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1474
1475 actuals2 = presentedSurfaceFrame2.getActuals();
1476 EXPECT_EQ(actuals2.presentTime, 65);
1477 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1478 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1479 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1480}
1481
1482TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001483 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001484 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001485 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1486 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001487 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1488 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1489 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001490 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001491 sUidOne, sLayerIdOne, sLayerNameOne,
1492 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001493 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001494 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001495 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1496 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1497 mFrameTimeline->setSfPresent(26, presentFence1);
1498 auto displayFrame1 = getDisplayFrame(0);
1499 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1500 presentFence1->signalForTest(50);
1501
1502 // Fences for the first frame haven't been flushed yet, so it should be 0
1503 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1504 auto actuals1 = presentedSurfaceFrame1.getActuals();
1505 EXPECT_EQ(actuals1.presentTime, 0);
1506
1507 // Trigger a flush by finalizing the next DisplayFrame
1508 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1509 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001510 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001511 sUidOne, sLayerIdOne, sLayerNameOne,
1512 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001513 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001514 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001515 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1516 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001517 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001518 auto displayFrame2 = getDisplayFrame(1);
1519 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1520
1521 // Fences for the first frame have flushed, so the present timestamps should be updated
1522 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1523 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1524 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1525 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1526
1527 actuals1 = presentedSurfaceFrame1.getActuals();
1528 EXPECT_EQ(actuals1.presentTime, 50);
1529 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1530 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1531 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1532
1533 // Fences for the second frame haven't been flushed yet, so it should be 0
1534 presentFence2->signalForTest(86);
1535 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1536 auto actuals2 = presentedSurfaceFrame2.getActuals();
1537 EXPECT_EQ(actuals2.presentTime, 0);
1538
Alec Mouri363faf02021-01-29 16:34:55 -08001539 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1540
1541 EXPECT_CALL(*mTimeStats,
1542 incrementJankyFrames(
1543 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
1544 sLayerNameOne, JankType::PredictionError, 0, 5,
1545 0}));
1546
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001547 addEmptyDisplayFrame();
1548
1549 // Fences for the second frame have flushed, so the present timestamps should be updated
1550 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1551 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1552 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1553 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1554
1555 actuals2 = presentedSurfaceFrame2.getActuals();
1556 EXPECT_EQ(actuals2.presentTime, 86);
1557 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1558 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1559 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1560}
1561
1562TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001563 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08001564
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001565 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001566 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001567 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
1568 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001569 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001570 sUidOne, sLayerIdOne, sLayerNameOne,
1571 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001572 surfaceFrame1->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001573 mFrameTimeline->setSfWakeUp(sfToken1, 42, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001574 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1575 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1576 mFrameTimeline->setSfPresent(46, presentFence1);
1577 auto displayFrame1 = getDisplayFrame(0);
1578 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1579 presentFence1->signalForTest(50);
1580
1581 // Fences for the first frame haven't been flushed yet, so it should be 0
1582 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1583 auto actuals1 = presentedSurfaceFrame1.getActuals();
1584 EXPECT_EQ(actuals1.presentTime, 0);
1585
1586 addEmptyDisplayFrame();
1587
1588 // Fences for the first frame have flushed, so the present timestamps should be updated
1589 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1590 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1591 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1592 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1593
1594 actuals1 = presentedSurfaceFrame1.getActuals();
1595 EXPECT_EQ(actuals1.presentTime, 50);
1596 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1597 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1598 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
1599}
1600
1601TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
1602 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as
1603 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
1604 // jank to the SurfaceFrame.
1605
Alec Mouri363faf02021-01-29 16:34:55 -08001606 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001607 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001608 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
1609 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001610 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1611 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
1612 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001613 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001614 sUidOne, sLayerIdOne, sLayerNameOne,
1615 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001616 surfaceFrame1->setAcquireFenceTime(26);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001617 mFrameTimeline->setSfWakeUp(sfToken1, 32, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001618 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1619 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1620 mFrameTimeline->setSfPresent(36, presentFence1);
1621 auto displayFrame1 = getDisplayFrame(0);
1622 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1623 presentFence1->signalForTest(40);
1624
1625 // Fences for the first frame haven't been flushed yet, so it should be 0
1626 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1627 auto actuals1 = presentedSurfaceFrame1.getActuals();
1628 EXPECT_EQ(actuals1.presentTime, 0);
1629
1630 // Trigger a flush by finalizing the next DisplayFrame
1631 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1632 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001633 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001634 sUidOne, sLayerIdOne, sLayerNameOne,
1635 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001636 surfaceFrame2->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001637 mFrameTimeline->setSfWakeUp(sfToken2, 43, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001638 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1639 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1640 mFrameTimeline->setSfPresent(56, presentFence2);
1641 auto displayFrame2 = getDisplayFrame(1);
1642 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1643
1644 // Fences for the first frame have flushed, so the present timestamps should be updated
1645 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
1646 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1647 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1648 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1649
1650 actuals1 = presentedSurfaceFrame1.getActuals();
1651 EXPECT_EQ(actuals1.presentTime, 40);
1652 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1653 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1654 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1655
1656 // Fences for the second frame haven't been flushed yet, so it should be 0
1657 presentFence2->signalForTest(60);
1658 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1659 auto actuals2 = presentedSurfaceFrame2.getActuals();
1660 EXPECT_EQ(actuals2.presentTime, 0);
1661
1662 addEmptyDisplayFrame();
1663
1664 // Fences for the second frame have flushed, so the present timestamps should be updated
1665 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
1666 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1667 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1668 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1669
1670 actuals2 = presentedSurfaceFrame2.getActuals();
1671 EXPECT_EQ(actuals2.presentTime, 60);
1672 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1673 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1674 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1675}
1676
1677TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001678 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001679 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001680 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1681 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
1682 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
1683
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001684 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
1685 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001686 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001687 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001688 sUidOne, sLayerIdOne, sLayerNameOne,
1689 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001690 surfaceFrame1->setAcquireFenceTime(50);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001691 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001692 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1693 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1694 mFrameTimeline->setSfPresent(56, presentFence1);
1695 auto displayFrame1 = getDisplayFrame(0);
1696 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1697 presentFence1->signalForTest(60);
1698
1699 // Fences for the first frame haven't been flushed yet, so it should be 0
1700 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1701 auto actuals1 = presentedSurfaceFrame1.getActuals();
1702 EXPECT_EQ(actuals1.presentTime, 0);
1703
1704 // Trigger a flush by finalizing the next DisplayFrame
1705 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1706 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001707 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001708 sUidOne, sLayerIdOne, sLayerNameOne,
1709 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001710 surfaceFrame2->setAcquireFenceTime(84);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001711 mFrameTimeline->setSfWakeUp(sfToken2, 112, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001712 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
1713 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1714 mFrameTimeline->setSfPresent(116, presentFence2);
1715 auto displayFrame2 = getDisplayFrame(1);
1716 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1717 presentFence2->signalForTest(120);
1718
1719 // Fences for the first frame have flushed, so the present timestamps should be updated
1720 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
1721 actuals1 = presentedSurfaceFrame1.getActuals();
1722 EXPECT_EQ(actuals1.endTime, 50);
1723 EXPECT_EQ(actuals1.presentTime, 60);
1724
1725 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1726 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1727 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1728
1729 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1730 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1731 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1732
1733 // Fences for the second frame haven't been flushed yet, so it should be 0
1734 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1735 auto actuals2 = presentedSurfaceFrame2.getActuals();
1736 EXPECT_EQ(actuals2.presentTime, 0);
1737
1738 addEmptyDisplayFrame();
1739
1740 // Fences for the second frame have flushed, so the present timestamps should be updated
1741 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1742 actuals2 = presentedSurfaceFrame2.getActuals();
1743 EXPECT_EQ(actuals2.presentTime, 120);
1744
1745 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1746 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1747 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
1748
1749 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1750 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1751 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
1752 JankType::AppDeadlineMissed | JankType::BufferStuffing);
1753}
Alec Mouriadebf5c2021-01-05 12:57:36 -08001754
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001755TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
1756 // Layer specific increment
1757 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
1758 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1759 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
1760 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
1761
1762 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
1763 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1764 auto surfaceFrame1 =
1765 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1766 sUidOne, sLayerIdOne, sLayerNameOne,
1767 sLayerNameOne);
1768 surfaceFrame1->setAcquireFenceTime(50);
1769 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
1770 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1771 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1772 mFrameTimeline->setSfPresent(56, presentFence1);
1773 auto displayFrame1 = getDisplayFrame(0);
1774 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1775 presentFence1->signalForTest(60);
1776
1777 // Fences for the first frame haven't been flushed yet, so it should be 0
1778 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1779 auto actuals1 = presentedSurfaceFrame1.getActuals();
1780 EXPECT_EQ(actuals1.presentTime, 0);
1781
1782 // Trigger a flush by finalizing the next DisplayFrame
1783 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1784 auto surfaceFrame2 =
1785 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1786 sUidOne, sLayerIdOne, sLayerNameOne,
1787 sLayerNameOne);
1788 surfaceFrame2->setAcquireFenceTime(80);
1789 mFrameTimeline->setSfWakeUp(sfToken2, 82, Fps::fromPeriodNsecs(30));
1790 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
1791 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
1792 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1793 mFrameTimeline->setSfPresent(86, presentFence2);
1794 auto displayFrame2 = getDisplayFrame(1);
1795 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1796 presentFence2->signalForTest(90);
1797
1798 // Fences for the first frame have flushed, so the present timestamps should be updated
1799 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
1800 actuals1 = presentedSurfaceFrame1.getActuals();
1801 EXPECT_EQ(actuals1.endTime, 50);
1802 EXPECT_EQ(actuals1.presentTime, 60);
1803
1804 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1805 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1806 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1807
1808 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1809 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1810 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1811
1812 // Fences for the second frame haven't been flushed yet, so it should be 0
1813 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1814 auto actuals2 = presentedSurfaceFrame2.getActuals();
1815 EXPECT_EQ(actuals2.presentTime, 0);
1816
1817 addEmptyDisplayFrame();
1818
1819 // Fences for the second frame have flushed, so the present timestamps should be updated
1820 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
1821 actuals2 = presentedSurfaceFrame2.getActuals();
1822 EXPECT_EQ(actuals2.presentTime, 90);
1823
1824 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1825 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1826 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
1827
1828 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1829 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1830 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
1831}
1832
Alec Mouriadebf5c2021-01-05 12:57:36 -08001833TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
1834 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
1835}
1836
1837TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001838 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08001839
1840 auto surfaceFrame1 =
1841 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1842 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1843 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1844 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1845 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1846 presentFence1->signalForTest(oneHundredMs);
1847 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
1848
1849 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
1850}
1851
1852TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001853 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
1854 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08001855 auto surfaceFrame1 =
1856 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1857 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1858 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1859 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1860 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1861 presentFence1->signalForTest(oneHundredMs);
1862 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
1863
1864 auto surfaceFrame2 =
1865 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1866 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1867 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1868 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1869 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1870 presentFence2->signalForTest(twoHundredMs);
1871 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
1872
1873 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
1874}
1875
1876TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001877 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
1878 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08001879 auto surfaceFrame1 =
1880 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1881 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1882 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1883 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1884 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1885 presentFence1->signalForTest(oneHundredMs);
1886 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
1887
1888 auto surfaceFrame2 =
1889 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1890 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo);
1891 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1892 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1893 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1894 presentFence2->signalForTest(twoHundredMs);
1895 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
1896
1897 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
1898}
1899
1900TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001901 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
1902 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08001903 auto surfaceFrame1 =
1904 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1905 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1906 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1907 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1908 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1909 presentFence1->signalForTest(oneHundredMs);
1910 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
1911
1912 auto surfaceFrame2 =
1913 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1914 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo);
1915 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1916 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1917 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1918 presentFence2->signalForTest(twoHundredMs);
1919 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
1920
1921 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
1922}
1923
1924TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001925 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
1926 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
1927 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
1928 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
1929 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08001930 auto surfaceFrame1 =
1931 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1932 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1933 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1934 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1935 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1936 presentFence1->signalForTest(oneHundredMs);
1937 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
1938
1939 auto surfaceFrame2 =
1940 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1941 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1942 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1943 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1944 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1945 presentFence2->signalForTest(twoHundredMs);
1946 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
1947
1948 auto surfaceFrame3 =
1949 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1950 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo);
1951 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1952 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
1953 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
1954 presentFence3->signalForTest(threeHundredMs);
1955 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
1956
1957 auto surfaceFrame4 =
1958 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1959 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1960 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1961 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
1962 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
1963 presentFence4->signalForTest(fiveHundredMs);
1964 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
1965
1966 auto surfaceFrame5 =
1967 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1968 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1969 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1970 // Dropped frames will be excluded from fps computation
1971 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
1972 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
1973 presentFence5->signalForTest(sixHundredMs);
1974 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
1975
1976 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
1977}
1978
Adithya Srinivasanf279e042020-08-17 14:56:27 -07001979} // namespace android::frametimeline