blob: 81efe0b270153e92e76f3c271d1e22daa880cdec [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 Srinivasan7c4ac7a2021-03-08 23:48:03 +0000423TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
424 Fps refreshRate = Fps::fromPeriodNsecs(11);
425
426 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
427 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
428 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
429
430 auto surfaceFrame1 =
431 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
432 sUidOne, sLayerIdOne, sLayerNameOne,
433 sLayerNameOne);
434 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
435 surfaceFrame1->setAcquireFenceTime(20);
436 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
437 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
438
439 mFrameTimeline->setSfPresent(59, presentFence1);
440 presentFence1->signalForTest(-1);
441 addEmptyDisplayFrame();
442
443 auto displayFrame0 = getDisplayFrame(0);
444 EXPECT_EQ(displayFrame0->getActuals().presentTime, -1);
445 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown);
446 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
447 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
448}
449
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800450// Tests related to TimeStats
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000451TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
452 Fps refreshRate = Fps::fromPeriodNsecs(11);
453 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
454 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
455 int64_t surfaceFrameToken1 = -1;
456 int64_t sfToken1 = -1;
457
458 auto surfaceFrame1 =
459 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
460 sUidOne, sLayerIdOne, sLayerNameOne,
461 sLayerNameOne);
462 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
463 surfaceFrame1->setAcquireFenceTime(20);
464 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
465 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
466 presentFence1->signalForTest(70);
467
468 mFrameTimeline->setSfPresent(59, presentFence1);
469}
470
Alec Mouri9a29e672020-09-14 12:39:14 -0700471TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000472 Fps refreshRate = Fps::fromPeriodNsecs(11);
473 // Deadline delta is 2ms because, sf's adjusted deadline is 60 - composerTime(3) = 57ms.
Alec Mouri9a29e672020-09-14 12:39:14 -0700474 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800475 incrementJankyFrames(
476 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
477 sLayerNameOne,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000478 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800479 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700480 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000481 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
482 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
483
Alec Mouri9a29e672020-09-14 12:39:14 -0700484 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000485 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800486 sUidOne, sLayerIdOne, sLayerNameOne,
487 sLayerNameOne);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000488 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
489 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800490 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
491 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000492 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700493
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000494 mFrameTimeline->setSfPresent(59, presentFence1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700495}
496
497TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800498 Fps refreshRate = Fps::fromPeriodNsecs(30);
Alec Mouri9a29e672020-09-14 12:39:14 -0700499 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800500 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
501 sLayerNameOne, JankType::DisplayHAL,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000502 -1, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800503
Alec Mouri9a29e672020-09-14 12:39:14 -0700504 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000505 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
506 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
507
Alec Mouri9a29e672020-09-14 12:39:14 -0700508 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000509 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800510 sUidOne, sLayerIdOne, sLayerNameOne,
511 sLayerNameOne);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000512 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800513 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000514 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800515 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000516 presentFence1->signalForTest(90);
517 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800518 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700519}
520
521TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800522 Fps refreshRate = Fps(11.0);
Alec Mouri9a29e672020-09-14 12:39:14 -0700523 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000524 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
525 sLayerNameOne,
526 JankType::AppDeadlineMissed, -1, 0,
527 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700528 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000529 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
530 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
531
Alec Mouri9a29e672020-09-14 12:39:14 -0700532 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000533 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800534 sUidOne, sLayerIdOne, sLayerNameOne,
535 sLayerNameOne);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000536 surfaceFrame1->setAcquireFenceTime(45);
537 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700538
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800539 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
540 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000541 presentFence1->signalForTest(90);
542 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100543
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800544 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700545}
546
Adithya Srinivasanead17162021-02-18 02:17:37 +0000547TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000548 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000549 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000550 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
551 sLayerNameOne,
552 JankType::SurfaceFlingerScheduling,
553 -1, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000554 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000555 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
556 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
557
Adithya Srinivasanead17162021-02-18 02:17:37 +0000558 auto surfaceFrame1 =
559 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800560 sUidOne, sLayerIdOne, sLayerNameOne,
561 sLayerNameOne);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000562 surfaceFrame1->setAcquireFenceTime(50);
563 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000564
565 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
566 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000567 presentFence1->signalForTest(60);
568 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000569
570 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
571}
572
573TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000574 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000575 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000576 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
577 sLayerNameOne,
578 JankType::PredictionError, -1, 5,
579 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000580 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000581 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
582 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
583
Adithya Srinivasanead17162021-02-18 02:17:37 +0000584 auto surfaceFrame1 =
585 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800586 sUidOne, sLayerIdOne, sLayerNameOne,
587 sLayerNameOne);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000588 surfaceFrame1->setAcquireFenceTime(40);
589 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000590
591 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
592 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000593 presentFence1->signalForTest(65);
594 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000595
596 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
597}
598
599TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000600 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000601 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000602 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
603 sLayerNameOne,
604 JankType::BufferStuffing, -1, 0,
605 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000606 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000607 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
608 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
609
Adithya Srinivasanead17162021-02-18 02:17:37 +0000610 auto surfaceFrame1 =
611 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800612 sUidOne, sLayerIdOne, sLayerNameOne,
613 sLayerNameOne);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000614 surfaceFrame1->setAcquireFenceTime(40);
615 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000616
617 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000618 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000619 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000620 presentFence1->signalForTest(90);
621 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000622
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000623 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000624}
625
Alec Mouri363faf02021-01-29 16:34:55 -0800626TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000627 Fps refreshRate = Fps::fromPeriodNsecs(11);
628 Fps renderRate = Fps::fromPeriodNsecs(30);
Alec Mouri363faf02021-01-29 16:34:55 -0800629 EXPECT_CALL(*mTimeStats,
630 incrementJankyFrames(
631 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000632 JankType::AppDeadlineMissed, -1, 0, 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800633 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000634 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
635 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
636
Alec Mouri363faf02021-01-29 16:34:55 -0800637 auto surfaceFrame1 =
638 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800639 sUidOne, sLayerIdOne, sLayerNameOne,
640 sLayerNameOne);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000641 surfaceFrame1->setAcquireFenceTime(45);
642 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800643
644 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
645 surfaceFrame1->setRenderRate(renderRate);
646 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000647 presentFence1->signalForTest(90);
648 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800649
650 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
651}
652
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000653TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
654 Fps refreshRate = Fps::fromPeriodNsecs(11);
655 Fps renderRate = Fps::fromPeriodNsecs(30);
656
657 EXPECT_CALL(*mTimeStats,
658 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne,
659 sLayerNameOne, JankType::Unknown,
660 -1, -1, 25}));
661 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
662 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
663 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
664
665 auto surfaceFrame1 =
666 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
667 sUidOne, sLayerIdOne, sLayerNameOne,
668 sLayerNameOne);
669 surfaceFrame1->setAcquireFenceTime(45);
670 // Trigger a prediction expiry
671 flushTokens(systemTime() + maxTokenRetentionTime);
672 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
673
674 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
675 surfaceFrame1->setRenderRate(renderRate);
676 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
677 presentFence1->signalForTest(90);
678 mFrameTimeline->setSfPresent(86, presentFence1);
679
680 auto displayFrame = getDisplayFrame(0);
681 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
682 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
683 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
684 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
685
686 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
687 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
688}
689
Adithya Srinivasan01189672020-10-20 14:23:05 -0700690/*
691 * Tracing Tests
692 *
693 * Trace packets are flushed all the way only when the next packet is traced.
694 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
695 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
696 * will have additional empty frames created for this reason.
697 */
698TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
699 auto tracingSession = getTracingSessionForTest();
700 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700701 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000702 auto surfaceFrame1 =
703 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800704 sLayerIdOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700705
706 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800707 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800708 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
709 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700710 mFrameTimeline->setSfPresent(25, presentFence1);
711 presentFence1->signalForTest(30);
712
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000713 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700714
715 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000716 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700717}
718
719TEST_F(FrameTimelineTest, tracing_sanityTest) {
720 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800721 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800722 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700723 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700724
725 tracingSession->StartBlocking();
726 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
727 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000728 auto surfaceFrame1 =
729 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800730 sLayerIdOne, sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700731
732 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800733 mFrameTimeline->setSfWakeUp(token2, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800734 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
735 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700736 mFrameTimeline->setSfPresent(25, presentFence1);
737 presentFence1->signalForTest(30);
738
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000739 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000740 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700741 tracingSession->StopBlocking();
742
743 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000744 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000745 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700746}
747
748TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
749 auto tracingSession = getTracingSessionForTest();
750 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700751
752 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700753
754 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800755 mFrameTimeline->setSfWakeUp(-1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700756 mFrameTimeline->setSfPresent(25, presentFence1);
757 presentFence1->signalForTest(30);
758
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000759 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000760 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700761 tracingSession->StopBlocking();
762
763 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000764 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700765}
766
767TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
768 auto tracingSession = getTracingSessionForTest();
769 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700770
771 tracingSession->StartBlocking();
772 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -0800773 auto surfaceFrame1 =
774 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
775 sLayerNameOne, sLayerNameOne);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700776
777 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800778 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800779 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
780 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700781 mFrameTimeline->setSfPresent(25, presentFence1);
782 presentFence1->signalForTest(30);
783
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000784 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000785 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700786 tracingSession->StopBlocking();
787
788 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000789 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
790 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000791 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700792}
793
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000794ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
795 pid_t pid) {
796 ProtoExpectedDisplayFrameStart proto;
797 proto.set_cookie(cookie);
798 proto.set_token(token);
799 proto.set_pid(pid);
800 return proto;
801}
802
803ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
804 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000805 bool gpuComposition, ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000806 ProtoActualDisplayFrameStart proto;
807 proto.set_cookie(cookie);
808 proto.set_token(token);
809 proto.set_pid(pid);
810 proto.set_present_type(presentType);
811 proto.set_on_time_finish(onTimeFinish);
812 proto.set_gpu_composition(gpuComposition);
813 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000814 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000815 return proto;
816}
817
818ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
819 int64_t displayFrameToken,
820 pid_t pid,
821 std::string layerName) {
822 ProtoExpectedSurfaceFrameStart proto;
823 proto.set_cookie(cookie);
824 proto.set_token(token);
825 proto.set_display_frame_token(displayFrameToken);
826 proto.set_pid(pid);
827 proto.set_layer_name(layerName);
828 return proto;
829}
830
831ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
832 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
833 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000834 ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000835 ProtoActualSurfaceFrameStart proto;
836 proto.set_cookie(cookie);
837 proto.set_token(token);
838 proto.set_display_frame_token(displayFrameToken);
839 proto.set_pid(pid);
840 proto.set_layer_name(layerName);
841 proto.set_present_type(presentType);
842 proto.set_on_time_finish(onTimeFinish);
843 proto.set_gpu_composition(gpuComposition);
844 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000845 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000846 return proto;
847}
848
849ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
850 ProtoFrameEnd proto;
851 proto.set_cookie(cookie);
852 return proto;
853}
854
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000855void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
856 const ProtoExpectedDisplayFrameStart& source) {
857 ASSERT_TRUE(received.has_cookie());
858 EXPECT_EQ(received.cookie(), source.cookie());
859
Adithya Srinivasan01189672020-10-20 14:23:05 -0700860 ASSERT_TRUE(received.has_token());
861 EXPECT_EQ(received.token(), source.token());
862
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000863 ASSERT_TRUE(received.has_pid());
864 EXPECT_EQ(received.pid(), source.pid());
865}
866
867void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
868 const ProtoActualDisplayFrameStart& source) {
869 ASSERT_TRUE(received.has_cookie());
870 EXPECT_EQ(received.cookie(), source.cookie());
871
872 ASSERT_TRUE(received.has_token());
873 EXPECT_EQ(received.token(), source.token());
874
875 ASSERT_TRUE(received.has_pid());
876 EXPECT_EQ(received.pid(), source.pid());
877
Adithya Srinivasan01189672020-10-20 14:23:05 -0700878 ASSERT_TRUE(received.has_present_type());
879 EXPECT_EQ(received.present_type(), source.present_type());
880 ASSERT_TRUE(received.has_on_time_finish());
881 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
882 ASSERT_TRUE(received.has_gpu_composition());
883 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
884 ASSERT_TRUE(received.has_jank_type());
885 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000886 ASSERT_TRUE(received.has_prediction_type());
887 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700888}
889
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000890void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
891 const ProtoExpectedSurfaceFrameStart& source) {
892 ASSERT_TRUE(received.has_cookie());
893 EXPECT_EQ(received.cookie(), source.cookie());
894
Adithya Srinivasan01189672020-10-20 14:23:05 -0700895 ASSERT_TRUE(received.has_token());
896 EXPECT_EQ(received.token(), source.token());
897
898 ASSERT_TRUE(received.has_display_frame_token());
899 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
900
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000901 ASSERT_TRUE(received.has_pid());
902 EXPECT_EQ(received.pid(), source.pid());
903
904 ASSERT_TRUE(received.has_layer_name());
905 EXPECT_EQ(received.layer_name(), source.layer_name());
906}
907
908void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
909 const ProtoActualSurfaceFrameStart& source) {
910 ASSERT_TRUE(received.has_cookie());
911 EXPECT_EQ(received.cookie(), source.cookie());
912
913 ASSERT_TRUE(received.has_token());
914 EXPECT_EQ(received.token(), source.token());
915
916 ASSERT_TRUE(received.has_display_frame_token());
917 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
918
919 ASSERT_TRUE(received.has_pid());
920 EXPECT_EQ(received.pid(), source.pid());
921
922 ASSERT_TRUE(received.has_layer_name());
923 EXPECT_EQ(received.layer_name(), source.layer_name());
924
Adithya Srinivasan01189672020-10-20 14:23:05 -0700925 ASSERT_TRUE(received.has_present_type());
926 EXPECT_EQ(received.present_type(), source.present_type());
927 ASSERT_TRUE(received.has_on_time_finish());
928 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
929 ASSERT_TRUE(received.has_gpu_composition());
930 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
931 ASSERT_TRUE(received.has_jank_type());
932 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000933 ASSERT_TRUE(received.has_prediction_type());
934 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000935}
Adithya Srinivasan01189672020-10-20 14:23:05 -0700936
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000937void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
938 ASSERT_TRUE(received.has_cookie());
939 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700940}
941
942TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
943 auto tracingSession = getTracingSessionForTest();
944 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700945
946 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000947 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -0700948
949 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800950 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700951 mFrameTimeline->setSfPresent(26, presentFence1);
952 presentFence1->signalForTest(31);
953
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000954 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000955 auto protoExpectedDisplayFrameStart =
956 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
957 kSurfaceFlingerPid);
958 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
959 auto protoActualDisplayFrameStart =
960 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
961 kSurfaceFlingerPid,
962 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000963 FrameTimelineEvent::JANK_NONE,
964 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000965 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000966
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000967 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000968 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700969 tracingSession->StopBlocking();
970
971 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000972 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700973
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000974 // Packet - 0 : ExpectedDisplayFrameStart
975 const auto& packet0 = packets[0];
976 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000977 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000978 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700979
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000980 const auto& event0 = packet0.frame_timeline_event();
981 ASSERT_TRUE(event0.has_expected_display_frame_start());
982 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
983 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
984
985 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
986 const auto& packet1 = packets[1];
987 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000988 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000989 ASSERT_TRUE(packet1.has_frame_timeline_event());
990
991 const auto& event1 = packet1.frame_timeline_event();
992 ASSERT_TRUE(event1.has_frame_end());
993 const auto& expectedDisplayFrameEnd = event1.frame_end();
994 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
995
996 // Packet - 2 : ActualDisplayFrameStart
997 const auto& packet2 = packets[2];
998 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000999 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001000 ASSERT_TRUE(packet2.has_frame_timeline_event());
1001
1002 const auto& event2 = packet2.frame_timeline_event();
1003 ASSERT_TRUE(event2.has_actual_display_frame_start());
1004 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1005 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1006
1007 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1008 const auto& packet3 = packets[3];
1009 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001010 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001011 ASSERT_TRUE(packet3.has_frame_timeline_event());
1012
1013 const auto& event3 = packet3.frame_timeline_event();
1014 ASSERT_TRUE(event3.has_frame_end());
1015 const auto& actualDisplayFrameEnd = event3.frame_end();
1016 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001017}
1018
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001019TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1020 auto tracingSession = getTracingSessionForTest();
1021 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1022
1023 tracingSession->StartBlocking();
1024 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1025 // Flush the token so that it would expire
1026 flushTokens(systemTime() + maxTokenRetentionTime);
1027
1028 // Set up the display frame
1029 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
1030 mFrameTimeline->setSfPresent(26, presentFence1);
1031 presentFence1->signalForTest(31);
1032
1033 int64_t traceCookie = snoopCurrentTraceCookie();
1034
1035 auto protoActualDisplayFrameStart =
1036 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1037 kSurfaceFlingerPid,
1038 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001039 false, FrameTimelineEvent::JANK_UNKNOWN,
1040 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001041 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1042
1043 addEmptyDisplayFrame();
1044 flushTrace();
1045 tracingSession->StopBlocking();
1046
1047 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1048 // Only actual timeline packets should be in the trace
1049 EXPECT_EQ(packets.size(), 2u);
1050
1051 // Packet - 0 : ActualDisplayFrameStart
1052 const auto& packet0 = packets[0];
1053 ASSERT_TRUE(packet0.has_timestamp());
1054 EXPECT_EQ(packet0.timestamp(), 20u);
1055 ASSERT_TRUE(packet0.has_frame_timeline_event());
1056
1057 const auto& event0 = packet0.frame_timeline_event();
1058 ASSERT_TRUE(event0.has_actual_display_frame_start());
1059 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1060 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1061
1062 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1063 const auto& packet1 = packets[1];
1064 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001065 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001066 ASSERT_TRUE(packet1.has_frame_timeline_event());
1067
1068 const auto& event1 = packet1.frame_timeline_event();
1069 ASSERT_TRUE(event1.has_frame_end());
1070 const auto& actualDisplayFrameEnd = event1.frame_end();
1071 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1072}
1073
Adithya Srinivasan01189672020-10-20 14:23:05 -07001074TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1075 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001076 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001077 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -07001078 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1079 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1080
1081 tracingSession->StartBlocking();
1082 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1083 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001084
1085 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001086 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001087 sUidOne, sLayerIdOne, sLayerNameOne,
1088 sLayerNameOne);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001089 auto surfaceFrame2 =
1090 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001091 sUidOne, sLayerIdOne, sLayerNameOne,
1092 sLayerNameOne);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001093 surfaceFrame1->setActualQueueTime(10);
1094 surfaceFrame1->setDropTime(15);
1095
1096 surfaceFrame2->setActualQueueTime(15);
1097 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001098
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001099 // First 2 cookies will be used by the DisplayFrame
1100 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1101
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001102 auto protoDroppedSurfaceFrameExpectedStart =
1103 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1104 displayFrameToken1, sPidOne, sLayerNameOne);
1105 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1106 auto protoDroppedSurfaceFrameActualStart =
1107 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1108 displayFrameToken1, sPidOne, sLayerNameOne,
1109 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001110 FrameTimelineEvent::JANK_NONE,
1111 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001112 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001113
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001114 auto protoPresentedSurfaceFrameExpectedStart =
1115 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1116 displayFrameToken1, sPidOne, sLayerNameOne);
1117 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1118 auto protoPresentedSurfaceFrameActualStart =
1119 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1120 displayFrameToken1, sPidOne, sLayerNameOne,
1121 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001122 FrameTimelineEvent::JANK_NONE,
1123 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001124 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001125
1126 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -08001127 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001128 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1129 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001130 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001131 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001132 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001133 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001134
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001135 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001136 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001137 tracingSession->StopBlocking();
1138
1139 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001140 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1141 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001142
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001143 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001144 const auto& packet4 = packets[4];
1145 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001146 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001147 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001148
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001149 const auto& event4 = packet4.frame_timeline_event();
1150 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001151 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1152 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001153
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001154 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001155 const auto& packet5 = packets[5];
1156 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001157 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001158 ASSERT_TRUE(packet5.has_frame_timeline_event());
1159
1160 const auto& event5 = packet5.frame_timeline_event();
1161 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001162 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1163 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001164
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001165 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001166 const auto& packet6 = packets[6];
1167 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001168 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001169 ASSERT_TRUE(packet6.has_frame_timeline_event());
1170
1171 const auto& event6 = packet6.frame_timeline_event();
1172 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001173 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1174 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001175
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001176 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001177 const auto& packet7 = packets[7];
1178 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001179 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001180 ASSERT_TRUE(packet7.has_frame_timeline_event());
1181
1182 const auto& event7 = packet7.frame_timeline_event();
1183 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001184 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1185 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1186
1187 // Packet - 8 : ExpectedSurfaceFrameStart2
1188 const auto& packet8 = packets[8];
1189 ASSERT_TRUE(packet8.has_timestamp());
1190 EXPECT_EQ(packet8.timestamp(), 10u);
1191 ASSERT_TRUE(packet8.has_frame_timeline_event());
1192
1193 const auto& event8 = packet8.frame_timeline_event();
1194 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1195 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1196 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1197
1198 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1199 const auto& packet9 = packets[9];
1200 ASSERT_TRUE(packet9.has_timestamp());
1201 EXPECT_EQ(packet9.timestamp(), 25u);
1202 ASSERT_TRUE(packet9.has_frame_timeline_event());
1203
1204 const auto& event9 = packet9.frame_timeline_event();
1205 ASSERT_TRUE(event9.has_frame_end());
1206 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1207 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1208
1209 // Packet - 10 : ActualSurfaceFrameStart2
1210 const auto& packet10 = packets[10];
1211 ASSERT_TRUE(packet10.has_timestamp());
1212 EXPECT_EQ(packet10.timestamp(), 10u);
1213 ASSERT_TRUE(packet10.has_frame_timeline_event());
1214
1215 const auto& event10 = packet10.frame_timeline_event();
1216 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1217 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1218 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1219
1220 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1221 const auto& packet11 = packets[11];
1222 ASSERT_TRUE(packet11.has_timestamp());
1223 EXPECT_EQ(packet11.timestamp(), 20u);
1224 ASSERT_TRUE(packet11.has_frame_timeline_event());
1225
1226 const auto& event11 = packet11.frame_timeline_event();
1227 ASSERT_TRUE(event11.has_frame_end());
1228 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1229 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1230}
1231
1232TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1233 auto tracingSession = getTracingSessionForTest();
1234 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1235
1236 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001237 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1238 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1239 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001240 int64_t surfaceFrameToken =
1241 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1242
1243 // Flush the token so that it would expire
1244 flushTokens(systemTime() + maxTokenRetentionTime);
1245 auto surfaceFrame1 =
1246 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0},
Alec Mouriadebf5c2021-01-05 12:57:36 -08001247 sPidOne, sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001248 sLayerNameOne);
1249 surfaceFrame1->setActualQueueTime(appEndTime);
1250 surfaceFrame1->setAcquireFenceTime(appEndTime);
1251
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001252 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1253 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1254 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001255 int64_t displayFrameToken =
1256 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1257
1258 // First 2 cookies will be used by the DisplayFrame
1259 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1260
1261 auto protoActualSurfaceFrameStart =
1262 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1263 displayFrameToken, sPidOne, sLayerNameOne,
1264 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001265 false, FrameTimelineEvent::JANK_UNKNOWN,
1266 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001267 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1268
1269 // Set up the display frame
1270 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1271 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1272 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1273 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1274 presentFence1->signalForTest(sfPresentTime);
1275
1276 addEmptyDisplayFrame();
1277 flushTrace();
1278 tracingSession->StopBlocking();
1279
1280 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1281 // Display Frame 4 packets + SurfaceFrame 2 packets
1282 ASSERT_EQ(packets.size(), 6u);
1283
1284 // Packet - 4 : ActualSurfaceFrameStart
1285 const auto& packet4 = packets[4];
1286 ASSERT_TRUE(packet4.has_timestamp());
1287 EXPECT_EQ(packet4.timestamp(),
1288 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1289 ASSERT_TRUE(packet4.has_frame_timeline_event());
1290
1291 const auto& event4 = packet4.frame_timeline_event();
1292 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1293 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1294 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1295
1296 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1297 const auto& packet5 = packets[5];
1298 ASSERT_TRUE(packet5.has_timestamp());
1299 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1300 ASSERT_TRUE(packet5.has_frame_timeline_event());
1301
1302 const auto& event5 = packet5.frame_timeline_event();
1303 ASSERT_TRUE(event5.has_frame_end());
1304 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001305 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001306}
1307
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001308// Tests for Jank classification
1309TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001310 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001311 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001312 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1313 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001314 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001315 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001316 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001317 sUidOne, sLayerIdOne, sLayerNameOne,
1318 sLayerNameOne);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001319 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001320 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1321 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1322 mFrameTimeline->setSfPresent(26, presentFence1);
1323 auto displayFrame = getDisplayFrame(0);
1324 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1325 presentFence1->signalForTest(29);
1326
1327 // Fences haven't been flushed yet, so it should be 0
1328 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1329 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1330
1331 addEmptyDisplayFrame();
1332 displayFrame = getDisplayFrame(0);
1333
1334 // Fences have flushed, so the present timestamps should be updated
1335 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1336 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1337 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1338 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1339 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
1340}
1341
1342TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001343 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001344 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001345 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1346 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001347 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001348 mFrameTimeline->setSfPresent(26, presentFence1);
1349 auto displayFrame = getDisplayFrame(0);
1350 presentFence1->signalForTest(30);
1351
1352 // Fences for the first frame haven't been flushed yet, so it should be 0
1353 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1354
1355 // Trigger a flush by finalizing the next DisplayFrame
1356 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001357 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001358 mFrameTimeline->setSfPresent(56, presentFence2);
1359 displayFrame = getDisplayFrame(0);
1360
1361 // Fences for the first frame have flushed, so the present timestamps should be updated
1362 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1363 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1364 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1365 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1366
1367 // Fences for the second frame haven't been flushed yet, so it should be 0
1368 auto displayFrame2 = getDisplayFrame(1);
1369 presentFence2->signalForTest(65);
1370 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001371 addEmptyDisplayFrame();
1372 displayFrame2 = getDisplayFrame(1);
1373
1374 // Fences for the second frame have flushed, so the present timestamps should be updated
1375 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1376 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1377 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1378 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1379}
1380
1381TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001382 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001383 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001384 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1385 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001386 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001387 mFrameTimeline->setSfPresent(26, presentFence1);
1388 auto displayFrame = getDisplayFrame(0);
1389 presentFence1->signalForTest(50);
1390
1391 // Fences for the first frame haven't been flushed yet, so it should be 0
1392 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1393
1394 // Trigger a flush by finalizing the next DisplayFrame
1395 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001396 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001397 mFrameTimeline->setSfPresent(56, presentFence2);
1398 displayFrame = getDisplayFrame(0);
1399
1400 // Fences for the first frame have flushed, so the present timestamps should be updated
1401 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1402 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1403 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1404 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1405
1406 // Fences for the second frame haven't been flushed yet, so it should be 0
1407 auto displayFrame2 = getDisplayFrame(1);
1408 presentFence2->signalForTest(75);
1409 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1410
1411 addEmptyDisplayFrame();
1412 displayFrame2 = getDisplayFrame(1);
1413
1414 // Fences for the second frame have flushed, so the present timestamps should be updated
1415 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1416 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1417 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1418 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1419}
1420
1421TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001422 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1423 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001424 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001425
1426 mFrameTimeline->setSfPresent(22, presentFence1);
1427 auto displayFrame = getDisplayFrame(0);
1428 presentFence1->signalForTest(28);
1429
1430 // Fences haven't been flushed yet, so it should be 0
1431 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1432
1433 addEmptyDisplayFrame();
1434 displayFrame = getDisplayFrame(0);
1435
1436 // Fences have flushed, so the present timestamps should be updated
1437 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1438 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1439 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1440 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1441}
1442
1443TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001444 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1445 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001446 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001447 mFrameTimeline->setSfPresent(36, presentFence1);
1448 auto displayFrame = getDisplayFrame(0);
1449 presentFence1->signalForTest(52);
1450
1451 // Fences haven't been flushed yet, so it should be 0
1452 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1453
1454 addEmptyDisplayFrame();
1455 displayFrame = getDisplayFrame(0);
1456
1457 // Fences have flushed, so the present timestamps should be updated
1458 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
1459 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1460 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1461 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1462}
1463
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001464TEST_F(FrameTimelineTest, jankClassification_displayFrameLateStartLateFinishLatePresent) {
1465 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1466 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
1467 mFrameTimeline->setSfWakeUp(sfToken1, 26, Fps::fromPeriodNsecs(11));
1468 mFrameTimeline->setSfPresent(36, presentFence1);
1469 auto displayFrame = getDisplayFrame(0);
1470 presentFence1->signalForTest(52);
1471
1472 // Fences haven't been flushed yet, so it should be 0
1473 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1474
1475 addEmptyDisplayFrame();
1476 displayFrame = getDisplayFrame(0);
1477
1478 // Fences have flushed, so the present timestamps should be updated
1479 EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
1480 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::LateStart);
1481 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1482 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1483 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1484}
1485
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001486TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001487 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001488 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001489 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1490 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001491 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1492 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1493 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001494 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001495 sUidOne, sLayerIdOne, sLayerNameOne,
1496 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001497 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001498 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001499 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1500 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001501 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001502 auto displayFrame1 = getDisplayFrame(0);
1503 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1504 presentFence1->signalForTest(30);
1505
1506 // Fences for the first frame haven't been flushed yet, so it should be 0
1507 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1508 auto actuals1 = presentedSurfaceFrame1.getActuals();
1509 EXPECT_EQ(actuals1.presentTime, 0);
1510
1511 // Trigger a flush by finalizing the next DisplayFrame
1512 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1513 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001514 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001515 sUidOne, sLayerIdOne, sLayerNameOne,
1516 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001517 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001518 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001519 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1520 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001521 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001522 auto displayFrame2 = getDisplayFrame(1);
1523 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1524
1525 // Fences for the first frame have flushed, so the present timestamps should be updated
1526 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1527 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1528 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1529 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1530
1531 actuals1 = presentedSurfaceFrame1.getActuals();
1532 EXPECT_EQ(actuals1.presentTime, 30);
1533 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1534 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1535 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1536
1537 // Fences for the second frame haven't been flushed yet, so it should be 0
1538 presentFence2->signalForTest(65);
1539 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1540 auto actuals2 = presentedSurfaceFrame2.getActuals();
1541 EXPECT_EQ(actuals2.presentTime, 0);
1542
Alec Mouri363faf02021-01-29 16:34:55 -08001543 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1544
1545 EXPECT_CALL(*mTimeStats,
1546 incrementJankyFrames(
1547 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
1548 sLayerNameOne, JankType::PredictionError, 0, 5,
1549 0}));
1550
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001551 addEmptyDisplayFrame();
1552
1553 // Fences for the second frame have flushed, so the present timestamps should be updated
1554 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1555 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1556 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1557 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1558
1559 actuals2 = presentedSurfaceFrame2.getActuals();
1560 EXPECT_EQ(actuals2.presentTime, 65);
1561 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1562 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1563 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1564}
1565
1566TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001567 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001568 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001569 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1570 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001571 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1572 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1573 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001574 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001575 sUidOne, sLayerIdOne, sLayerNameOne,
1576 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001577 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001578 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001579 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1580 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1581 mFrameTimeline->setSfPresent(26, presentFence1);
1582 auto displayFrame1 = getDisplayFrame(0);
1583 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1584 presentFence1->signalForTest(50);
1585
1586 // Fences for the first frame haven't been flushed yet, so it should be 0
1587 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1588 auto actuals1 = presentedSurfaceFrame1.getActuals();
1589 EXPECT_EQ(actuals1.presentTime, 0);
1590
1591 // Trigger a flush by finalizing the next DisplayFrame
1592 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1593 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001594 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001595 sUidOne, sLayerIdOne, sLayerNameOne,
1596 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001597 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001598 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001599 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1600 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001601 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001602 auto displayFrame2 = getDisplayFrame(1);
1603 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1604
1605 // Fences for the first frame have flushed, so the present timestamps should be updated
1606 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1607 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1608 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1609 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1610
1611 actuals1 = presentedSurfaceFrame1.getActuals();
1612 EXPECT_EQ(actuals1.presentTime, 50);
1613 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1614 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1615 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1616
1617 // Fences for the second frame haven't been flushed yet, so it should be 0
1618 presentFence2->signalForTest(86);
1619 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1620 auto actuals2 = presentedSurfaceFrame2.getActuals();
1621 EXPECT_EQ(actuals2.presentTime, 0);
1622
Alec Mouri363faf02021-01-29 16:34:55 -08001623 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1624
1625 EXPECT_CALL(*mTimeStats,
1626 incrementJankyFrames(
1627 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
1628 sLayerNameOne, JankType::PredictionError, 0, 5,
1629 0}));
1630
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001631 addEmptyDisplayFrame();
1632
1633 // Fences for the second frame have flushed, so the present timestamps should be updated
1634 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1635 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1636 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1637 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1638
1639 actuals2 = presentedSurfaceFrame2.getActuals();
1640 EXPECT_EQ(actuals2.presentTime, 86);
1641 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1642 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1643 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1644}
1645
1646TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001647 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08001648
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001649 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001650 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001651 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
1652 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001653 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001654 sUidOne, sLayerIdOne, sLayerNameOne,
1655 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001656 surfaceFrame1->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001657 mFrameTimeline->setSfWakeUp(sfToken1, 42, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001658 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1659 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1660 mFrameTimeline->setSfPresent(46, presentFence1);
1661 auto displayFrame1 = getDisplayFrame(0);
1662 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1663 presentFence1->signalForTest(50);
1664
1665 // Fences for the first frame haven't been flushed yet, so it should be 0
1666 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1667 auto actuals1 = presentedSurfaceFrame1.getActuals();
1668 EXPECT_EQ(actuals1.presentTime, 0);
1669
1670 addEmptyDisplayFrame();
1671
1672 // Fences for the first frame have flushed, so the present timestamps should be updated
1673 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1674 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1675 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1676 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1677
1678 actuals1 = presentedSurfaceFrame1.getActuals();
1679 EXPECT_EQ(actuals1.presentTime, 50);
1680 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1681 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1682 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
1683}
1684
1685TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
1686 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as
1687 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
1688 // jank to the SurfaceFrame.
1689
Alec Mouri363faf02021-01-29 16:34:55 -08001690 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001691 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001692 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
1693 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001694 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1695 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
1696 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001697 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001698 sUidOne, sLayerIdOne, sLayerNameOne,
1699 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001700 surfaceFrame1->setAcquireFenceTime(26);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001701 mFrameTimeline->setSfWakeUp(sfToken1, 32, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001702 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1703 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1704 mFrameTimeline->setSfPresent(36, presentFence1);
1705 auto displayFrame1 = getDisplayFrame(0);
1706 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1707 presentFence1->signalForTest(40);
1708
1709 // Fences for the first frame haven't been flushed yet, so it should be 0
1710 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1711 auto actuals1 = presentedSurfaceFrame1.getActuals();
1712 EXPECT_EQ(actuals1.presentTime, 0);
1713
1714 // Trigger a flush by finalizing the next DisplayFrame
1715 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1716 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001717 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001718 sUidOne, sLayerIdOne, sLayerNameOne,
1719 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001720 surfaceFrame2->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001721 mFrameTimeline->setSfWakeUp(sfToken2, 43, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001722 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1723 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1724 mFrameTimeline->setSfPresent(56, presentFence2);
1725 auto displayFrame2 = getDisplayFrame(1);
1726 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1727
1728 // Fences for the first frame have flushed, so the present timestamps should be updated
1729 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
1730 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1731 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1732 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1733
1734 actuals1 = presentedSurfaceFrame1.getActuals();
1735 EXPECT_EQ(actuals1.presentTime, 40);
1736 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1737 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1738 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1739
1740 // Fences for the second frame haven't been flushed yet, so it should be 0
1741 presentFence2->signalForTest(60);
1742 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1743 auto actuals2 = presentedSurfaceFrame2.getActuals();
1744 EXPECT_EQ(actuals2.presentTime, 0);
1745
1746 addEmptyDisplayFrame();
1747
1748 // Fences for the second frame have flushed, so the present timestamps should be updated
1749 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
1750 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1751 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1752 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1753
1754 actuals2 = presentedSurfaceFrame2.getActuals();
1755 EXPECT_EQ(actuals2.presentTime, 60);
1756 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1757 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1758 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1759}
1760
1761TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001762 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001763 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001764 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1765 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
1766 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
1767
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001768 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
1769 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001770 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001771 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001772 sUidOne, sLayerIdOne, sLayerNameOne,
1773 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001774 surfaceFrame1->setAcquireFenceTime(50);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001775 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001776 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1777 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1778 mFrameTimeline->setSfPresent(56, presentFence1);
1779 auto displayFrame1 = getDisplayFrame(0);
1780 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1781 presentFence1->signalForTest(60);
1782
1783 // Fences for the first frame haven't been flushed yet, so it should be 0
1784 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1785 auto actuals1 = presentedSurfaceFrame1.getActuals();
1786 EXPECT_EQ(actuals1.presentTime, 0);
1787
1788 // Trigger a flush by finalizing the next DisplayFrame
1789 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1790 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001791 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001792 sUidOne, sLayerIdOne, sLayerNameOne,
1793 sLayerNameOne);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001794 surfaceFrame2->setAcquireFenceTime(84);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001795 mFrameTimeline->setSfWakeUp(sfToken2, 112, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001796 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
1797 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1798 mFrameTimeline->setSfPresent(116, presentFence2);
1799 auto displayFrame2 = getDisplayFrame(1);
1800 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1801 presentFence2->signalForTest(120);
1802
1803 // Fences for the first frame have flushed, so the present timestamps should be updated
1804 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
1805 actuals1 = presentedSurfaceFrame1.getActuals();
1806 EXPECT_EQ(actuals1.endTime, 50);
1807 EXPECT_EQ(actuals1.presentTime, 60);
1808
1809 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1810 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1811 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1812
1813 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1814 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1815 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1816
1817 // Fences for the second frame haven't been flushed yet, so it should be 0
1818 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1819 auto actuals2 = presentedSurfaceFrame2.getActuals();
1820 EXPECT_EQ(actuals2.presentTime, 0);
1821
1822 addEmptyDisplayFrame();
1823
1824 // Fences for the second frame have flushed, so the present timestamps should be updated
1825 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1826 actuals2 = presentedSurfaceFrame2.getActuals();
1827 EXPECT_EQ(actuals2.presentTime, 120);
1828
1829 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1830 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1831 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
1832
1833 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1834 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1835 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
1836 JankType::AppDeadlineMissed | JankType::BufferStuffing);
1837}
Alec Mouriadebf5c2021-01-05 12:57:36 -08001838
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001839TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
1840 // Layer specific increment
1841 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
1842 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1843 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
1844 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
1845
1846 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
1847 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1848 auto surfaceFrame1 =
1849 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
1850 sUidOne, sLayerIdOne, sLayerNameOne,
1851 sLayerNameOne);
1852 surfaceFrame1->setAcquireFenceTime(50);
1853 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
1854 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1855 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1856 mFrameTimeline->setSfPresent(56, presentFence1);
1857 auto displayFrame1 = getDisplayFrame(0);
1858 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1859 presentFence1->signalForTest(60);
1860
1861 // Fences for the first frame haven't been flushed yet, so it should be 0
1862 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1863 auto actuals1 = presentedSurfaceFrame1.getActuals();
1864 EXPECT_EQ(actuals1.presentTime, 0);
1865
1866 // Trigger a flush by finalizing the next DisplayFrame
1867 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1868 auto surfaceFrame2 =
1869 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
1870 sUidOne, sLayerIdOne, sLayerNameOne,
1871 sLayerNameOne);
1872 surfaceFrame2->setAcquireFenceTime(80);
1873 mFrameTimeline->setSfWakeUp(sfToken2, 82, Fps::fromPeriodNsecs(30));
1874 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
1875 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
1876 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1877 mFrameTimeline->setSfPresent(86, presentFence2);
1878 auto displayFrame2 = getDisplayFrame(1);
1879 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1880 presentFence2->signalForTest(90);
1881
1882 // Fences for the first frame have flushed, so the present timestamps should be updated
1883 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
1884 actuals1 = presentedSurfaceFrame1.getActuals();
1885 EXPECT_EQ(actuals1.endTime, 50);
1886 EXPECT_EQ(actuals1.presentTime, 60);
1887
1888 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1889 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1890 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1891
1892 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1893 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1894 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1895
1896 // Fences for the second frame haven't been flushed yet, so it should be 0
1897 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1898 auto actuals2 = presentedSurfaceFrame2.getActuals();
1899 EXPECT_EQ(actuals2.presentTime, 0);
1900
1901 addEmptyDisplayFrame();
1902
1903 // Fences for the second frame have flushed, so the present timestamps should be updated
1904 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
1905 actuals2 = presentedSurfaceFrame2.getActuals();
1906 EXPECT_EQ(actuals2.presentTime, 90);
1907
1908 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1909 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1910 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
1911
1912 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1913 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1914 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
1915}
1916
Alec Mouriadebf5c2021-01-05 12:57:36 -08001917TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
1918 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
1919}
1920
1921TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001922 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08001923
1924 auto surfaceFrame1 =
1925 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1926 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1927 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1928 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1929 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1930 presentFence1->signalForTest(oneHundredMs);
1931 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
1932
1933 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
1934}
1935
1936TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001937 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
1938 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08001939 auto surfaceFrame1 =
1940 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1941 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1942 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1943 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1944 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1945 presentFence1->signalForTest(oneHundredMs);
1946 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
1947
1948 auto surfaceFrame2 =
1949 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1950 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1951 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1952 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1953 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1954 presentFence2->signalForTest(twoHundredMs);
1955 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
1956
1957 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
1958}
1959
1960TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001961 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
1962 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08001963 auto surfaceFrame1 =
1964 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1965 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1966 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1967 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1968 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1969 presentFence1->signalForTest(oneHundredMs);
1970 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
1971
1972 auto surfaceFrame2 =
1973 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1974 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo);
1975 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1976 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1977 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1978 presentFence2->signalForTest(twoHundredMs);
1979 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
1980
1981 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
1982}
1983
1984TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001985 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
1986 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08001987 auto surfaceFrame1 =
1988 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1989 sLayerIdOne, sLayerNameOne, sLayerNameOne);
1990 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1991 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1992 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1993 presentFence1->signalForTest(oneHundredMs);
1994 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
1995
1996 auto surfaceFrame2 =
1997 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
1998 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo);
1999 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2000 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2001 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2002 presentFence2->signalForTest(twoHundredMs);
2003 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2004
2005 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2006}
2007
2008TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002009 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2010 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2011 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2012 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2013 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002014 auto surfaceFrame1 =
2015 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
2016 sLayerIdOne, sLayerNameOne, sLayerNameOne);
2017 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2018 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2019 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2020 presentFence1->signalForTest(oneHundredMs);
2021 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2022
2023 auto surfaceFrame2 =
2024 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
2025 sLayerIdOne, sLayerNameOne, sLayerNameOne);
2026 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2027 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2028 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2029 presentFence2->signalForTest(twoHundredMs);
2030 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2031
2032 auto surfaceFrame3 =
2033 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
2034 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo);
2035 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2036 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2037 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2038 presentFence3->signalForTest(threeHundredMs);
2039 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2040
2041 auto surfaceFrame4 =
2042 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
2043 sLayerIdOne, sLayerNameOne, sLayerNameOne);
2044 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2045 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2046 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2047 presentFence4->signalForTest(fiveHundredMs);
2048 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2049
2050 auto surfaceFrame5 =
2051 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
2052 sLayerIdOne, sLayerNameOne, sLayerNameOne);
2053 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2054 // Dropped frames will be excluded from fps computation
2055 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2056 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2057 presentFence5->signalForTest(sixHundredMs);
2058 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2059
2060 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2061}
2062
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002063} // namespace android::frametimeline