blob: 397c6193bfab0a77998b3de7890275c20d172de4 [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 Srinivasan82eef322021-04-10 00:06:04 +000071 kTestThresholds);
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 Srinivasanbed4c4f2021-05-03 20:24:46 +000076 maxTokens = mTokenManager->kMaxTokens;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070077 }
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 Srinivasanbed4c4f2021-05-03 20:24:46 +0000114 void flushTokens() {
115 for (size_t i = 0; i < maxTokens; i++) {
116 mTokenManager->generateTokenForPredictions({});
117 }
118 EXPECT_EQ(getPredictions().size(), maxTokens);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700119 }
120
121 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
122 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800123 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
124 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700125 }
126
127 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
128 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
129 return mFrameTimeline->mDisplayFrames[idx];
130 }
131
132 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
133 return a.startTime == b.startTime && a.endTime == b.endTime &&
134 a.presentTime == b.presentTime;
135 }
136
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000137 const std::map<int64_t, TimelineItem>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700138 return mTokenManager->mPredictions;
139 }
140
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000141 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700142 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
143 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
144 }
145
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000146 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
147
148 void flushTrace() {
149 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
150 FrameTimelineDataSource::Trace(
151 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
152 }
153
Alec Mouri9a29e672020-09-14 12:39:14 -0700154 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700155 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
156 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000157 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700158 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700159 uint32_t* maxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000160 size_t maxTokens;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000161 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasanead17162021-02-18 02:17:37 +0000162 static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan54996e22021-06-25 22:26:45 +0000163 static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(0ns).count();
Adithya Srinivasanead17162021-02-18 02:17:37 +0000164 static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800165 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
166 kDeadlineThreshold,
167 kStartThreshold};
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700168};
169
Alec Mouri9a29e672020-09-14 12:39:14 -0700170static const std::string sLayerNameOne = "layer1";
171static const std::string sLayerNameTwo = "layer2";
Dominik Laskowskif5d0ea52021-09-26 17:27:01 -0700172
173constexpr const uid_t sUidOne = 0;
174constexpr pid_t sPidOne = 10;
175constexpr pid_t sPidTwo = 20;
176constexpr int32_t sInputEventId = 5;
177constexpr int32_t sLayerIdOne = 1;
178constexpr int32_t sLayerIdTwo = 2;
179constexpr GameMode sGameMode = GameMode::Unsupported;
Alec Mouri9a29e672020-09-14 12:39:14 -0700180
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700181TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
182 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000183 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000184 flushTokens();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700185 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
186 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
187
188 // token1 should have expired
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700189 EXPECT_EQ(predictions.has_value(), false);
190
191 predictions = mTokenManager->getPredictionsForToken(token2);
192 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
193}
194
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700195TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800196 auto surfaceFrame1 =
197 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000198 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000199 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -0800200 auto surfaceFrame2 =
201 mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000202 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000203 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700204 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
205 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
206}
207
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700208TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800209 auto surfaceFrame =
210 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000211 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000212 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700213 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
214}
215
216TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
217 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000218 flushTokens();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000219 auto surfaceFrame =
220 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000221 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000222 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700223
224 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
225}
226
227TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
228 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000229 auto surfaceFrame =
230 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000231 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000232 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700233
234 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
235 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
236}
237
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000238TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
239 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
240 constexpr int32_t inputEventId = 1;
241 auto surfaceFrame =
242 mFrameTimeline->createSurfaceFrameForToken({token1, inputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000243 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000244 /*isBuffer*/ true, sGameMode);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000245
246 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
247}
248
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700249TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
250 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700251 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000252 auto surfaceFrame1 =
253 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000254 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000255 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700256
257 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800258 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000259 surfaceFrame1->setDropTime(12);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800260 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
261 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700262 mFrameTimeline->setSfPresent(25, presentFence1);
263 presentFence1->signalForTest(30);
264
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000265 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700266
267 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
268 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000269 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
270 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700271 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
272}
273
274TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800275 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800276 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700277 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
278 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700279 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri9a29e672020-09-14 12:39:14 -0700280 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000281 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800282 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000283 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Alec Mouri9a29e672020-09-14 12:39:14 -0700284 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000285 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800286 sUidOne, sLayerIdTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000287 sLayerNameTwo, /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800288 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800289 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
290 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
291 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
292 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700293 mFrameTimeline->setSfPresent(26, presentFence1);
294 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800295 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
296 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700297 presentFence1->signalForTest(42);
298
299 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800300 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700301 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
302 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
303
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000304 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700305
306 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800307 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700308 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
309 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100310 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
311 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700312}
313
314TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
315 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
316 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800317 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800318 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800319 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700320 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700321 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
322 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
323 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
324 int64_t sfToken = mTokenManager->generateTokenForPredictions(
325 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700326 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000327 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId},
Alec Mouriadebf5c2021-01-05 12:57:36 -0800328 sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000329 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000330 /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800331 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800332 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
333 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700334 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
335 presentFence->signalForTest(32 + frameTimeFactor);
336 frameTimeFactor += 30;
337 }
338 auto displayFrame0 = getDisplayFrame(0);
339
340 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800341 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700342
343 // Add one more display frame
344 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
345 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
346 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
347 int64_t sfToken = mTokenManager->generateTokenForPredictions(
348 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700349 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000350 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800351 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000352 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800353 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800354 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
355 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700356 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
357 presentFence->signalForTest(32 + frameTimeFactor);
358 displayFrame0 = getDisplayFrame(0);
359
360 // The window should have slided by 1 now and the previous 0th display frame
361 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800362 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700363}
364
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700365TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000366 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
367 "acquireFenceAfterQueue",
368 "acquireFenceAfterQueue",
369 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700370 surfaceFrame->setActualQueueTime(123);
371 surfaceFrame->setAcquireFenceTime(456);
372 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
373}
374
375TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000376 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
377 "acquireFenceAfterQueue",
378 "acquireFenceAfterQueue",
379 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700380 surfaceFrame->setActualQueueTime(456);
381 surfaceFrame->setAcquireFenceTime(123);
382 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
383}
384
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700385TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
386 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
387 presentFence->signalForTest(2);
388
389 // Size shouldn't exceed maxDisplayFrames - 64
390 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700391 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800392 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000393 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000394 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700395 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800396 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800397 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
398 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700399 mFrameTimeline->setSfPresent(27, presentFence);
400 }
401 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
402
403 // Increase the size to 256
404 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000405 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700406
407 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700408 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800409 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000410 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000411 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700412 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800413 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800414 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
415 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700416 mFrameTimeline->setSfPresent(27, presentFence);
417 }
418 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
419
420 // Shrink the size to 128
421 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000422 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700423
424 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700425 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800426 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000427 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000428 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700429 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800430 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800431 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
432 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700433 mFrameTimeline->setSfPresent(27, presentFence);
434 }
435 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
436}
Alec Mouri9a29e672020-09-14 12:39:14 -0700437
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000438TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
439 Fps refreshRate = Fps::fromPeriodNsecs(11);
440
441 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
442 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
443 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
444
445 auto surfaceFrame1 =
446 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
447 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000448 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000449 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
450 surfaceFrame1->setAcquireFenceTime(20);
451 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
452 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
453
454 mFrameTimeline->setSfPresent(59, presentFence1);
455 presentFence1->signalForTest(-1);
456 addEmptyDisplayFrame();
457
458 auto displayFrame0 = getDisplayFrame(0);
459 EXPECT_EQ(displayFrame0->getActuals().presentTime, -1);
460 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown);
461 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
462 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
463}
464
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800465// Tests related to TimeStats
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000466TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
467 Fps refreshRate = Fps::fromPeriodNsecs(11);
468 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
469 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
470 int64_t surfaceFrameToken1 = -1;
471 int64_t sfToken1 = -1;
472
473 auto surfaceFrame1 =
474 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
475 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000476 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000477 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
478 surfaceFrame1->setAcquireFenceTime(20);
479 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
480 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
481 presentFence1->signalForTest(70);
482
483 mFrameTimeline->setSfPresent(59, presentFence1);
484}
485
Alec Mouri9a29e672020-09-14 12:39:14 -0700486TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000487 Fps refreshRate = Fps::fromPeriodNsecs(11);
Alec Mouri9a29e672020-09-14 12:39:14 -0700488 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800489 incrementJankyFrames(
490 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000491 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000492 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800493 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700494 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000495 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
496 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
497
Alec Mouri9a29e672020-09-14 12:39:14 -0700498 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000499 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800500 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000501 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000502 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
503 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800504 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
505 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000506 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700507
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000508 mFrameTimeline->setSfPresent(62, presentFence1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700509}
510
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000511TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfGpu) {
512 Fps refreshRate = Fps::fromPeriodNsecs(11);
513 EXPECT_CALL(*mTimeStats,
514 incrementJankyFrames(
515 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000516 sLayerNameOne, sGameMode,
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000517 JankType::SurfaceFlingerGpuDeadlineMissed, 4, 10,
518 0}));
519 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
520 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
521 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
522 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
523
524 auto surfaceFrame1 =
525 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
526 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000527 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000528 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
529 surfaceFrame1->setAcquireFenceTime(20);
530 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
531 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
532 gpuFence1->signalForTest(64);
533 presentFence1->signalForTest(70);
534
535 mFrameTimeline->setSfPresent(59, presentFence1, gpuFence1);
536}
537
Alec Mouri9a29e672020-09-14 12:39:14 -0700538TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800539 Fps refreshRate = Fps::fromPeriodNsecs(30);
Alec Mouri9a29e672020-09-14 12:39:14 -0700540 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800541 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000542 sLayerNameOne, sGameMode,
543 JankType::DisplayHAL, -4, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800544
Alec Mouri9a29e672020-09-14 12:39:14 -0700545 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000546 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
547 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
548
Alec Mouri9a29e672020-09-14 12:39:14 -0700549 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000550 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800551 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000552 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000553 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800554 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000555 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800556 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000557 presentFence1->signalForTest(90);
558 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800559 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700560}
561
562TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Dominik Laskowski6eab42d2021-09-13 14:34:13 -0700563 Fps refreshRate = 11_Hz;
Alec Mouri9a29e672020-09-14 12:39:14 -0700564 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000565 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000566 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000567 JankType::AppDeadlineMissed, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000568 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700569 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000570 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
571 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
572
Alec Mouri9a29e672020-09-14 12:39:14 -0700573 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000574 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800575 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000576 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000577 surfaceFrame1->setAcquireFenceTime(45);
578 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700579
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800580 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
581 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000582 presentFence1->signalForTest(90);
583 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100584
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800585 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700586}
587
Adithya Srinivasanead17162021-02-18 02:17:37 +0000588TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000589 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000590 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000591 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000592 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000593 JankType::SurfaceFlingerScheduling,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000594 -4, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000595 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000596 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
597 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
598
Adithya Srinivasanead17162021-02-18 02:17:37 +0000599 auto surfaceFrame1 =
600 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800601 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000602 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000603 surfaceFrame1->setAcquireFenceTime(50);
604 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000605
606 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
607 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000608 presentFence1->signalForTest(60);
609 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000610
611 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
612}
613
614TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000615 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000616 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000617 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000618 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000619 JankType::PredictionError, -4, 5,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000620 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000621 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000622 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
623 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
624
Adithya Srinivasanead17162021-02-18 02:17:37 +0000625 auto surfaceFrame1 =
626 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800627 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000628 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000629 surfaceFrame1->setAcquireFenceTime(40);
630 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000631
632 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
633 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000634 presentFence1->signalForTest(65);
635 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000636
637 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
638}
639
640TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000641 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000642 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000643 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000644 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000645 JankType::BufferStuffing, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000646 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000647 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000648 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
649 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
650
Adithya Srinivasanead17162021-02-18 02:17:37 +0000651 auto surfaceFrame1 =
652 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800653 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000654 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000655 surfaceFrame1->setAcquireFenceTime(40);
656 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000657
658 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000659 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000660 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000661 presentFence1->signalForTest(90);
662 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000663
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000664 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000665}
666
Alec Mouri363faf02021-01-29 16:34:55 -0800667TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000668 Fps refreshRate = Fps::fromPeriodNsecs(11);
669 Fps renderRate = Fps::fromPeriodNsecs(30);
Alec Mouri363faf02021-01-29 16:34:55 -0800670 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000671 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne,
672 sLayerNameOne, sGameMode,
673 JankType::AppDeadlineMissed, -4, 0,
674 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800675 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000676 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
677 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
678
Alec Mouri363faf02021-01-29 16:34:55 -0800679 auto surfaceFrame1 =
680 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800681 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000682 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000683 surfaceFrame1->setAcquireFenceTime(45);
684 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800685
686 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
687 surfaceFrame1->setRenderRate(renderRate);
688 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000689 presentFence1->signalForTest(90);
690 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800691
692 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
693}
694
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000695TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
696 Fps refreshRate = Fps::fromPeriodNsecs(11);
697 Fps renderRate = Fps::fromPeriodNsecs(30);
698
699 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000700 incrementJankyFrames(
701 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000702 sGameMode,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000703 JankType::Unknown | JankType::AppDeadlineMissed,
Adithya Srinivasande272452021-04-10 00:21:00 +0000704 0, 0, 25}));
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000705 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
706 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
707 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
708
709 auto surfaceFrame1 =
710 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
711 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000712 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000713 surfaceFrame1->setAcquireFenceTime(45);
714 // Trigger a prediction expiry
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000715 flushTokens();
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000716 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
717
718 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
719 surfaceFrame1->setRenderRate(renderRate);
720 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
721 presentFence1->signalForTest(90);
722 mFrameTimeline->setSfPresent(86, presentFence1);
723
724 auto displayFrame = getDisplayFrame(0);
725 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
726 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
727 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
728 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
729
730 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000731 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000732}
733
Adithya Srinivasan01189672020-10-20 14:23:05 -0700734/*
735 * Tracing Tests
736 *
737 * Trace packets are flushed all the way only when the next packet is traced.
738 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
739 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
740 * will have additional empty frames created for this reason.
741 */
742TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
743 auto tracingSession = getTracingSessionForTest();
744 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700745 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000746 auto surfaceFrame1 =
747 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000748 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000749 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700750
751 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800752 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800753 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
754 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700755 mFrameTimeline->setSfPresent(25, presentFence1);
756 presentFence1->signalForTest(30);
757
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000758 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700759
760 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000761 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700762}
763
764TEST_F(FrameTimelineTest, tracing_sanityTest) {
765 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800766 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800767 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700768 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700769
770 tracingSession->StartBlocking();
771 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
772 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000773 auto surfaceFrame1 =
774 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000775 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000776 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700777
778 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800779 mFrameTimeline->setSfWakeUp(token2, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800780 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
781 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700782 mFrameTimeline->setSfPresent(25, presentFence1);
783 presentFence1->signalForTest(30);
784
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000785 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000786 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700787 tracingSession->StopBlocking();
788
789 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000790 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000791 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700792}
793
794TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
795 auto tracingSession = getTracingSessionForTest();
796 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700797
798 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700799
800 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800801 mFrameTimeline->setSfWakeUp(-1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700802 mFrameTimeline->setSfPresent(25, presentFence1);
803 presentFence1->signalForTest(30);
804
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000805 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000806 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700807 tracingSession->StopBlocking();
808
809 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000810 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700811}
812
813TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
814 auto tracingSession = getTracingSessionForTest();
815 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700816
817 tracingSession->StartBlocking();
818 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -0800819 auto surfaceFrame1 =
820 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000821 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000822 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700823
824 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800825 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800826 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
827 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700828 mFrameTimeline->setSfPresent(25, presentFence1);
829 presentFence1->signalForTest(30);
830
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000831 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000832 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700833 tracingSession->StopBlocking();
834
835 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000836 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
837 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000838 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700839}
840
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000841ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
842 pid_t pid) {
843 ProtoExpectedDisplayFrameStart proto;
844 proto.set_cookie(cookie);
845 proto.set_token(token);
846 proto.set_pid(pid);
847 return proto;
848}
849
850ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
851 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000852 bool gpuComposition, ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000853 ProtoActualDisplayFrameStart proto;
854 proto.set_cookie(cookie);
855 proto.set_token(token);
856 proto.set_pid(pid);
857 proto.set_present_type(presentType);
858 proto.set_on_time_finish(onTimeFinish);
859 proto.set_gpu_composition(gpuComposition);
860 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000861 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000862 return proto;
863}
864
865ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
866 int64_t displayFrameToken,
867 pid_t pid,
868 std::string layerName) {
869 ProtoExpectedSurfaceFrameStart proto;
870 proto.set_cookie(cookie);
871 proto.set_token(token);
872 proto.set_display_frame_token(displayFrameToken);
873 proto.set_pid(pid);
874 proto.set_layer_name(layerName);
875 return proto;
876}
877
878ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
879 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
880 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +0000881 ProtoJankType jankType, ProtoPredictionType predictionType, bool isBuffer) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000882 ProtoActualSurfaceFrameStart proto;
883 proto.set_cookie(cookie);
884 proto.set_token(token);
885 proto.set_display_frame_token(displayFrameToken);
886 proto.set_pid(pid);
887 proto.set_layer_name(layerName);
888 proto.set_present_type(presentType);
889 proto.set_on_time_finish(onTimeFinish);
890 proto.set_gpu_composition(gpuComposition);
891 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000892 proto.set_prediction_type(predictionType);
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +0000893 proto.set_is_buffer(isBuffer);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000894 return proto;
895}
896
897ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
898 ProtoFrameEnd proto;
899 proto.set_cookie(cookie);
900 return proto;
901}
902
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000903void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
904 const ProtoExpectedDisplayFrameStart& source) {
905 ASSERT_TRUE(received.has_cookie());
906 EXPECT_EQ(received.cookie(), source.cookie());
907
Adithya Srinivasan01189672020-10-20 14:23:05 -0700908 ASSERT_TRUE(received.has_token());
909 EXPECT_EQ(received.token(), source.token());
910
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000911 ASSERT_TRUE(received.has_pid());
912 EXPECT_EQ(received.pid(), source.pid());
913}
914
915void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
916 const ProtoActualDisplayFrameStart& source) {
917 ASSERT_TRUE(received.has_cookie());
918 EXPECT_EQ(received.cookie(), source.cookie());
919
920 ASSERT_TRUE(received.has_token());
921 EXPECT_EQ(received.token(), source.token());
922
923 ASSERT_TRUE(received.has_pid());
924 EXPECT_EQ(received.pid(), source.pid());
925
Adithya Srinivasan01189672020-10-20 14:23:05 -0700926 ASSERT_TRUE(received.has_present_type());
927 EXPECT_EQ(received.present_type(), source.present_type());
928 ASSERT_TRUE(received.has_on_time_finish());
929 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
930 ASSERT_TRUE(received.has_gpu_composition());
931 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
932 ASSERT_TRUE(received.has_jank_type());
933 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000934 ASSERT_TRUE(received.has_prediction_type());
935 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700936}
937
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000938void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
939 const ProtoExpectedSurfaceFrameStart& source) {
940 ASSERT_TRUE(received.has_cookie());
941 EXPECT_EQ(received.cookie(), source.cookie());
942
Adithya Srinivasan01189672020-10-20 14:23:05 -0700943 ASSERT_TRUE(received.has_token());
944 EXPECT_EQ(received.token(), source.token());
945
946 ASSERT_TRUE(received.has_display_frame_token());
947 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
948
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000949 ASSERT_TRUE(received.has_pid());
950 EXPECT_EQ(received.pid(), source.pid());
951
952 ASSERT_TRUE(received.has_layer_name());
953 EXPECT_EQ(received.layer_name(), source.layer_name());
954}
955
956void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
957 const ProtoActualSurfaceFrameStart& source) {
958 ASSERT_TRUE(received.has_cookie());
959 EXPECT_EQ(received.cookie(), source.cookie());
960
961 ASSERT_TRUE(received.has_token());
962 EXPECT_EQ(received.token(), source.token());
963
964 ASSERT_TRUE(received.has_display_frame_token());
965 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
966
967 ASSERT_TRUE(received.has_pid());
968 EXPECT_EQ(received.pid(), source.pid());
969
970 ASSERT_TRUE(received.has_layer_name());
971 EXPECT_EQ(received.layer_name(), source.layer_name());
972
Adithya Srinivasan01189672020-10-20 14:23:05 -0700973 ASSERT_TRUE(received.has_present_type());
974 EXPECT_EQ(received.present_type(), source.present_type());
975 ASSERT_TRUE(received.has_on_time_finish());
976 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
977 ASSERT_TRUE(received.has_gpu_composition());
978 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
979 ASSERT_TRUE(received.has_jank_type());
980 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000981 ASSERT_TRUE(received.has_prediction_type());
982 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +0000983 ASSERT_TRUE(received.has_is_buffer());
984 EXPECT_EQ(received.is_buffer(), source.is_buffer());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000985}
Adithya Srinivasan01189672020-10-20 14:23:05 -0700986
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000987void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
988 ASSERT_TRUE(received.has_cookie());
989 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700990}
991
992TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
993 auto tracingSession = getTracingSessionForTest();
994 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700995
996 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000997 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -0700998
999 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -08001000 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -07001001 mFrameTimeline->setSfPresent(26, presentFence1);
1002 presentFence1->signalForTest(31);
1003
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001004 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001005 auto protoExpectedDisplayFrameStart =
1006 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1007 kSurfaceFlingerPid);
1008 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1009 auto protoActualDisplayFrameStart =
1010 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
1011 kSurfaceFlingerPid,
1012 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001013 FrameTimelineEvent::JANK_NONE,
1014 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001015 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001016
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001017 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001018 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001019 tracingSession->StopBlocking();
1020
1021 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001022 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001023
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001024 // Packet - 0 : ExpectedDisplayFrameStart
1025 const auto& packet0 = packets[0];
1026 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001027 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001028 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001029
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001030 const auto& event0 = packet0.frame_timeline_event();
1031 ASSERT_TRUE(event0.has_expected_display_frame_start());
1032 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
1033 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
1034
1035 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
1036 const auto& packet1 = packets[1];
1037 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001038 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001039 ASSERT_TRUE(packet1.has_frame_timeline_event());
1040
1041 const auto& event1 = packet1.frame_timeline_event();
1042 ASSERT_TRUE(event1.has_frame_end());
1043 const auto& expectedDisplayFrameEnd = event1.frame_end();
1044 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
1045
1046 // Packet - 2 : ActualDisplayFrameStart
1047 const auto& packet2 = packets[2];
1048 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001049 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001050 ASSERT_TRUE(packet2.has_frame_timeline_event());
1051
1052 const auto& event2 = packet2.frame_timeline_event();
1053 ASSERT_TRUE(event2.has_actual_display_frame_start());
1054 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1055 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1056
1057 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1058 const auto& packet3 = packets[3];
1059 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001060 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001061 ASSERT_TRUE(packet3.has_frame_timeline_event());
1062
1063 const auto& event3 = packet3.frame_timeline_event();
1064 ASSERT_TRUE(event3.has_frame_end());
1065 const auto& actualDisplayFrameEnd = event3.frame_end();
1066 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001067}
1068
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001069TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1070 auto tracingSession = getTracingSessionForTest();
1071 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1072
1073 tracingSession->StartBlocking();
1074 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1075 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001076 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001077
1078 // Set up the display frame
1079 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
1080 mFrameTimeline->setSfPresent(26, presentFence1);
1081 presentFence1->signalForTest(31);
1082
1083 int64_t traceCookie = snoopCurrentTraceCookie();
1084
1085 auto protoActualDisplayFrameStart =
1086 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1087 kSurfaceFlingerPid,
1088 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001089 false, FrameTimelineEvent::JANK_UNKNOWN,
1090 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001091 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1092
1093 addEmptyDisplayFrame();
1094 flushTrace();
1095 tracingSession->StopBlocking();
1096
1097 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1098 // Only actual timeline packets should be in the trace
1099 EXPECT_EQ(packets.size(), 2u);
1100
1101 // Packet - 0 : ActualDisplayFrameStart
1102 const auto& packet0 = packets[0];
1103 ASSERT_TRUE(packet0.has_timestamp());
1104 EXPECT_EQ(packet0.timestamp(), 20u);
1105 ASSERT_TRUE(packet0.has_frame_timeline_event());
1106
1107 const auto& event0 = packet0.frame_timeline_event();
1108 ASSERT_TRUE(event0.has_actual_display_frame_start());
1109 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1110 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1111
1112 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1113 const auto& packet1 = packets[1];
1114 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001115 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001116 ASSERT_TRUE(packet1.has_frame_timeline_event());
1117
1118 const auto& event1 = packet1.frame_timeline_event();
1119 ASSERT_TRUE(event1.has_frame_end());
1120 const auto& actualDisplayFrameEnd = event1.frame_end();
1121 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1122}
1123
Adithya Srinivasan01189672020-10-20 14:23:05 -07001124TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1125 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001126 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001127 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -07001128 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1129 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1130
1131 tracingSession->StartBlocking();
1132 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1133 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001134
1135 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001136 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001137 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001138 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001139 auto surfaceFrame2 =
1140 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001141 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001142 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001143 surfaceFrame1->setActualQueueTime(10);
1144 surfaceFrame1->setDropTime(15);
1145
1146 surfaceFrame2->setActualQueueTime(15);
1147 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001148
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001149 // First 2 cookies will be used by the DisplayFrame
1150 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1151
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001152 auto protoDroppedSurfaceFrameExpectedStart =
1153 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1154 displayFrameToken1, sPidOne, sLayerNameOne);
1155 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1156 auto protoDroppedSurfaceFrameActualStart =
1157 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1158 displayFrameToken1, sPidOne, sLayerNameOne,
1159 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001160 FrameTimelineEvent::JANK_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001161 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001162 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001163
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001164 auto protoPresentedSurfaceFrameExpectedStart =
1165 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1166 displayFrameToken1, sPidOne, sLayerNameOne);
1167 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1168 auto protoPresentedSurfaceFrameActualStart =
1169 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1170 displayFrameToken1, sPidOne, sLayerNameOne,
1171 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001172 FrameTimelineEvent::JANK_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001173 FrameTimelineEvent::PREDICTION_VALID, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001174 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001175
1176 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -08001177 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001178 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1179 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001180 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001181 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001182 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001183 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001184
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001185 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001186 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001187 tracingSession->StopBlocking();
1188
1189 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001190 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1191 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001192
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001193 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001194 const auto& packet4 = packets[4];
1195 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001196 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001197 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001198
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001199 const auto& event4 = packet4.frame_timeline_event();
1200 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001201 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1202 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001203
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001204 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001205 const auto& packet5 = packets[5];
1206 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001207 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001208 ASSERT_TRUE(packet5.has_frame_timeline_event());
1209
1210 const auto& event5 = packet5.frame_timeline_event();
1211 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001212 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1213 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001214
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001215 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001216 const auto& packet6 = packets[6];
1217 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001218 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001219 ASSERT_TRUE(packet6.has_frame_timeline_event());
1220
1221 const auto& event6 = packet6.frame_timeline_event();
1222 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001223 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1224 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001225
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001226 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001227 const auto& packet7 = packets[7];
1228 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001229 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001230 ASSERT_TRUE(packet7.has_frame_timeline_event());
1231
1232 const auto& event7 = packet7.frame_timeline_event();
1233 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001234 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1235 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1236
1237 // Packet - 8 : ExpectedSurfaceFrameStart2
1238 const auto& packet8 = packets[8];
1239 ASSERT_TRUE(packet8.has_timestamp());
1240 EXPECT_EQ(packet8.timestamp(), 10u);
1241 ASSERT_TRUE(packet8.has_frame_timeline_event());
1242
1243 const auto& event8 = packet8.frame_timeline_event();
1244 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1245 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1246 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1247
1248 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1249 const auto& packet9 = packets[9];
1250 ASSERT_TRUE(packet9.has_timestamp());
1251 EXPECT_EQ(packet9.timestamp(), 25u);
1252 ASSERT_TRUE(packet9.has_frame_timeline_event());
1253
1254 const auto& event9 = packet9.frame_timeline_event();
1255 ASSERT_TRUE(event9.has_frame_end());
1256 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1257 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1258
1259 // Packet - 10 : ActualSurfaceFrameStart2
1260 const auto& packet10 = packets[10];
1261 ASSERT_TRUE(packet10.has_timestamp());
1262 EXPECT_EQ(packet10.timestamp(), 10u);
1263 ASSERT_TRUE(packet10.has_frame_timeline_event());
1264
1265 const auto& event10 = packet10.frame_timeline_event();
1266 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1267 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1268 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1269
1270 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1271 const auto& packet11 = packets[11];
1272 ASSERT_TRUE(packet11.has_timestamp());
1273 EXPECT_EQ(packet11.timestamp(), 20u);
1274 ASSERT_TRUE(packet11.has_frame_timeline_event());
1275
1276 const auto& event11 = packet11.frame_timeline_event();
1277 ASSERT_TRUE(event11.has_frame_end());
1278 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1279 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1280}
1281
1282TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1283 auto tracingSession = getTracingSessionForTest();
1284 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1285
1286 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001287 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1288 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1289 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001290 int64_t surfaceFrameToken =
1291 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1292
1293 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001294 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001295 auto surfaceFrame1 =
1296 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0},
Alec Mouriadebf5c2021-01-05 12:57:36 -08001297 sPidOne, sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001298 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001299 surfaceFrame1->setActualQueueTime(appEndTime);
1300 surfaceFrame1->setAcquireFenceTime(appEndTime);
1301
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001302 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1303 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1304 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001305 int64_t displayFrameToken =
1306 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1307
1308 // First 2 cookies will be used by the DisplayFrame
1309 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1310
1311 auto protoActualSurfaceFrameStart =
1312 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1313 displayFrameToken, sPidOne, sLayerNameOne,
1314 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001315 false, FrameTimelineEvent::JANK_UNKNOWN,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001316 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001317 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1318
1319 // Set up the display frame
1320 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1321 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1322 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1323 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1324 presentFence1->signalForTest(sfPresentTime);
1325
1326 addEmptyDisplayFrame();
1327 flushTrace();
1328 tracingSession->StopBlocking();
1329
1330 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1331 // Display Frame 4 packets + SurfaceFrame 2 packets
1332 ASSERT_EQ(packets.size(), 6u);
1333
1334 // Packet - 4 : ActualSurfaceFrameStart
1335 const auto& packet4 = packets[4];
1336 ASSERT_TRUE(packet4.has_timestamp());
1337 EXPECT_EQ(packet4.timestamp(),
1338 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1339 ASSERT_TRUE(packet4.has_frame_timeline_event());
1340
1341 const auto& event4 = packet4.frame_timeline_event();
1342 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1343 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1344 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1345
1346 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1347 const auto& packet5 = packets[5];
1348 ASSERT_TRUE(packet5.has_timestamp());
1349 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1350 ASSERT_TRUE(packet5.has_frame_timeline_event());
1351
1352 const auto& event5 = packet5.frame_timeline_event();
1353 ASSERT_TRUE(event5.has_frame_end());
1354 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001355 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001356}
1357
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001358TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDroppedFramesTracedProperly) {
1359 auto tracingSession = getTracingSessionForTest();
1360 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1361
1362 tracingSession->StartBlocking();
1363 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1364 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1365 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
1366 int64_t surfaceFrameToken =
1367 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1368
1369 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001370 flushTokens();
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001371 auto surfaceFrame1 =
1372 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0},
1373 sPidOne, sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001374 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001375
1376 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(22ms).count();
1377 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1378 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
1379 int64_t displayFrameToken =
1380 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1381
1382 // First 2 cookies will be used by the DisplayFrame
1383 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1384
1385 auto protoActualSurfaceFrameStart =
1386 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1387 displayFrameToken, sPidOne, sLayerNameOne,
1388 FrameTimelineEvent::PRESENT_DROPPED, false, false,
1389 FrameTimelineEvent::JANK_NONE,
Adithya Srinivasan1f9450c2021-06-10 22:39:19 +00001390 FrameTimelineEvent::PREDICTION_EXPIRED, true);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001391 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1392
1393 // Set up the display frame
1394 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1395 surfaceFrame1->setDropTime(sfStartTime);
1396 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1397 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1398 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1399 presentFence1->signalForTest(sfPresentTime);
1400
1401 addEmptyDisplayFrame();
1402 flushTrace();
1403 tracingSession->StopBlocking();
1404
1405 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1406 // Display Frame 4 packets + SurfaceFrame 2 packets
1407 ASSERT_EQ(packets.size(), 6u);
1408
1409 // Packet - 4 : ActualSurfaceFrameStart
1410 const auto& packet4 = packets[4];
1411 ASSERT_TRUE(packet4.has_timestamp());
1412 EXPECT_EQ(packet4.timestamp(),
1413 static_cast<uint64_t>(sfStartTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1414 ASSERT_TRUE(packet4.has_frame_timeline_event());
1415
1416 const auto& event4 = packet4.frame_timeline_event();
1417 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1418 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1419 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1420
1421 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1422 const auto& packet5 = packets[5];
1423 ASSERT_TRUE(packet5.has_timestamp());
1424 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(sfStartTime));
1425 ASSERT_TRUE(packet5.has_frame_timeline_event());
1426
1427 const auto& event5 = packet5.frame_timeline_event();
1428 ASSERT_TRUE(event5.has_frame_end());
1429 const auto& actualSurfaceFrameEnd = event5.frame_end();
1430 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
1431}
1432
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001433// Tests for Jank classification
1434TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001435 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001436 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001437 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1438 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001439 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001440 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001441 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001442 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001443 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001444 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001445 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1446 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1447 mFrameTimeline->setSfPresent(26, presentFence1);
1448 auto displayFrame = getDisplayFrame(0);
1449 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1450 presentFence1->signalForTest(29);
1451
1452 // Fences haven't been flushed yet, so it should be 0
1453 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1454 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1455
1456 addEmptyDisplayFrame();
1457 displayFrame = getDisplayFrame(0);
1458
1459 // Fences have flushed, so the present timestamps should be updated
1460 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1461 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1462 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1463 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1464 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
1465}
1466
1467TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001468 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001469 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001470 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1471 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001472 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001473 mFrameTimeline->setSfPresent(26, presentFence1);
1474 auto displayFrame = getDisplayFrame(0);
1475 presentFence1->signalForTest(30);
1476
1477 // Fences for the first frame haven't been flushed yet, so it should be 0
1478 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1479
1480 // Trigger a flush by finalizing the next DisplayFrame
1481 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001482 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001483 mFrameTimeline->setSfPresent(56, presentFence2);
1484 displayFrame = getDisplayFrame(0);
1485
1486 // Fences for the first frame have flushed, so the present timestamps should be updated
1487 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1488 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1489 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1490 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1491
1492 // Fences for the second frame haven't been flushed yet, so it should be 0
1493 auto displayFrame2 = getDisplayFrame(1);
1494 presentFence2->signalForTest(65);
1495 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001496 addEmptyDisplayFrame();
1497 displayFrame2 = getDisplayFrame(1);
1498
1499 // Fences for the second frame have flushed, so the present timestamps should be updated
1500 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1501 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1502 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1503 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1504}
1505
1506TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001507 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001508 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001509 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1510 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001511 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001512 mFrameTimeline->setSfPresent(26, presentFence1);
1513 auto displayFrame = getDisplayFrame(0);
1514 presentFence1->signalForTest(50);
1515
1516 // Fences for the first frame haven't been flushed yet, so it should be 0
1517 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1518
1519 // Trigger a flush by finalizing the next DisplayFrame
1520 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001521 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001522 mFrameTimeline->setSfPresent(56, presentFence2);
1523 displayFrame = getDisplayFrame(0);
1524
1525 // Fences for the first frame have flushed, so the present timestamps should be updated
1526 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1527 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1528 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1529 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1530
1531 // Fences for the second frame haven't been flushed yet, so it should be 0
1532 auto displayFrame2 = getDisplayFrame(1);
1533 presentFence2->signalForTest(75);
1534 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1535
1536 addEmptyDisplayFrame();
1537 displayFrame2 = getDisplayFrame(1);
1538
1539 // Fences for the second frame have flushed, so the present timestamps should be updated
1540 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1541 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1542 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1543 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1544}
1545
1546TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001547 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1548 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001549 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001550
1551 mFrameTimeline->setSfPresent(22, presentFence1);
1552 auto displayFrame = getDisplayFrame(0);
1553 presentFence1->signalForTest(28);
1554
1555 // Fences haven't been flushed yet, so it should be 0
1556 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1557
1558 addEmptyDisplayFrame();
1559 displayFrame = getDisplayFrame(0);
1560
1561 // Fences have flushed, so the present timestamps should be updated
1562 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1563 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1564 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1565 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1566}
1567
1568TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001569 /*
1570 * Case 1 - cpu time > vsync period but combined time > deadline > deadline -> cpudeadlinemissed
1571 * Case 2 - cpu time < vsync period but combined time > deadline -> gpudeadlinemissed
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001572 * Case 3 - previous frame ran longer -> sf_stuffing
1573 * Case 4 - Long cpu under SF stuffing -> cpudeadlinemissed
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001574 */
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001575 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001576 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001577 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1578 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001579 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1580 auto gpuFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001581 auto gpuFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1582 auto gpuFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001583 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001584 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001585 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1586 int64_t sfToken4 = mTokenManager->generateTokenForPredictions({112, 120, 120});
1587
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001588 // case 1 - cpu time = 33 - 12 = 21, vsync period = 11
Alec Mouri7d436ec2021-01-27 20:40:50 -08001589 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001590 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
1591 auto displayFrame0 = getDisplayFrame(0);
1592 gpuFence1->signalForTest(36);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001593 presentFence1->signalForTest(52);
1594
1595 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001596 EXPECT_EQ(displayFrame0->getActuals().presentTime, 0);
1597
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001598 // case 2 - cpu time = 56 - 52 = 4, vsync period = 30
1599 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001600 mFrameTimeline->setSfPresent(56, presentFence2, gpuFence2);
1601 auto displayFrame1 = getDisplayFrame(1);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001602 gpuFence2->signalForTest(76);
1603 presentFence2->signalForTest(90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001604
1605 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1606 // Fences have flushed for first displayFrame, so the present timestamps should be updated
1607 EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
1608 EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1609 EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1610 EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001611
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001612 // case 3 - cpu time = 86 - 82 = 4, vsync period = 30
1613 mFrameTimeline->setSfWakeUp(sfToken3, 106, Fps::fromPeriodNsecs(30));
1614 mFrameTimeline->setSfPresent(112, presentFence3, gpuFence3);
1615 auto displayFrame2 = getDisplayFrame(2);
1616 gpuFence3->signalForTest(116);
1617 presentFence3->signalForTest(120);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001618
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001619 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001620 // Fences have flushed for second displayFrame, so the present timestamps should be updated
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001621 EXPECT_EQ(displayFrame1->getActuals().presentTime, 90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001622 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1623 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1624 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001625
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001626 // case 4 - cpu time = 86 - 82 = 4, vsync period = 30
1627 mFrameTimeline->setSfWakeUp(sfToken4, 120, Fps::fromPeriodNsecs(30));
1628 mFrameTimeline->setSfPresent(140, presentFence4, gpuFence4);
1629 auto displayFrame3 = getDisplayFrame(3);
1630 gpuFence4->signalForTest(156);
1631 presentFence4->signalForTest(180);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001632
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001633 EXPECT_EQ(displayFrame3->getActuals().presentTime, 0);
1634 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1635 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1636 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1637 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1638 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerStuffing);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001639
1640 addEmptyDisplayFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001641
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001642 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1643 EXPECT_EQ(displayFrame3->getActuals().presentTime, 180);
1644 EXPECT_EQ(displayFrame3->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1645 EXPECT_EQ(displayFrame3->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1646 EXPECT_EQ(displayFrame3->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001647}
1648
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001649TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001650 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001651 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001652 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1653 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001654 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1655 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1656 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001657 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001658 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001659 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001660 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001661 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001662 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1663 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001664 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001665 auto displayFrame1 = getDisplayFrame(0);
1666 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1667 presentFence1->signalForTest(30);
1668
1669 // Fences for the first frame haven't been flushed yet, so it should be 0
1670 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1671 auto actuals1 = presentedSurfaceFrame1.getActuals();
1672 EXPECT_EQ(actuals1.presentTime, 0);
1673
1674 // Trigger a flush by finalizing the next DisplayFrame
1675 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1676 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001677 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001678 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001679 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001680 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001681 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001682 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1683 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001684 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001685 auto displayFrame2 = getDisplayFrame(1);
1686 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1687
1688 // Fences for the first frame have flushed, so the present timestamps should be updated
1689 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1690 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1691 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1692 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1693
1694 actuals1 = presentedSurfaceFrame1.getActuals();
1695 EXPECT_EQ(actuals1.presentTime, 30);
1696 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1697 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1698 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1699
1700 // Fences for the second frame haven't been flushed yet, so it should be 0
1701 presentFence2->signalForTest(65);
1702 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1703 auto actuals2 = presentedSurfaceFrame2.getActuals();
1704 EXPECT_EQ(actuals2.presentTime, 0);
1705
Alec Mouri363faf02021-01-29 16:34:55 -08001706 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1707
1708 EXPECT_CALL(*mTimeStats,
1709 incrementJankyFrames(
1710 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001711 sLayerNameOne, sGameMode,
1712 JankType::PredictionError, -3, 5, 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08001713
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001714 addEmptyDisplayFrame();
1715
1716 // Fences for the second frame have flushed, so the present timestamps should be updated
1717 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1718 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1719 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1720 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1721
1722 actuals2 = presentedSurfaceFrame2.getActuals();
1723 EXPECT_EQ(actuals2.presentTime, 65);
1724 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1725 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1726 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1727}
1728
1729TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001730 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001731 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001732 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1733 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001734 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1735 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1736 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001737 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001738 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001739 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001740 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001741 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001742 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1743 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1744 mFrameTimeline->setSfPresent(26, presentFence1);
1745 auto displayFrame1 = getDisplayFrame(0);
1746 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1747 presentFence1->signalForTest(50);
1748
1749 // Fences for the first frame haven't been flushed yet, so it should be 0
1750 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1751 auto actuals1 = presentedSurfaceFrame1.getActuals();
1752 EXPECT_EQ(actuals1.presentTime, 0);
1753
1754 // Trigger a flush by finalizing the next DisplayFrame
1755 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1756 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001757 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001758 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001759 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001760 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001761 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001762 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1763 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001764 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001765 auto displayFrame2 = getDisplayFrame(1);
1766 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1767
1768 // Fences for the first frame have flushed, so the present timestamps should be updated
1769 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1770 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1771 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1772 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1773
1774 actuals1 = presentedSurfaceFrame1.getActuals();
1775 EXPECT_EQ(actuals1.presentTime, 50);
1776 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1777 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1778 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1779
1780 // Fences for the second frame haven't been flushed yet, so it should be 0
1781 presentFence2->signalForTest(86);
1782 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1783 auto actuals2 = presentedSurfaceFrame2.getActuals();
1784 EXPECT_EQ(actuals2.presentTime, 0);
1785
Alec Mouri363faf02021-01-29 16:34:55 -08001786 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1787
1788 EXPECT_CALL(*mTimeStats,
1789 incrementJankyFrames(
1790 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001791 sLayerNameOne, sGameMode,
1792 JankType::PredictionError, -3, 5, 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08001793
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001794 addEmptyDisplayFrame();
1795
1796 // Fences for the second frame have flushed, so the present timestamps should be updated
1797 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1798 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1799 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1800 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1801
1802 actuals2 = presentedSurfaceFrame2.getActuals();
1803 EXPECT_EQ(actuals2.presentTime, 86);
1804 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1805 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1806 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1807}
1808
1809TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001810 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08001811
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001812 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001813 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001814 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
1815 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001816 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001817 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001818 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001819 surfaceFrame1->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001820 mFrameTimeline->setSfWakeUp(sfToken1, 42, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001821 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1822 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1823 mFrameTimeline->setSfPresent(46, presentFence1);
1824 auto displayFrame1 = getDisplayFrame(0);
1825 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1826 presentFence1->signalForTest(50);
1827
1828 // Fences for the first frame haven't been flushed yet, so it should be 0
1829 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1830 auto actuals1 = presentedSurfaceFrame1.getActuals();
1831 EXPECT_EQ(actuals1.presentTime, 0);
1832
1833 addEmptyDisplayFrame();
1834
1835 // Fences for the first frame have flushed, so the present timestamps should be updated
1836 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1837 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1838 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1839 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1840
1841 actuals1 = presentedSurfaceFrame1.getActuals();
1842 EXPECT_EQ(actuals1.presentTime, 50);
1843 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1844 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1845 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
1846}
1847
1848TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001849 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as only
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001850 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001851 // jank to the SurfaceFrame along with AppDeadlineMissed.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001852
Alec Mouri363faf02021-01-29 16:34:55 -08001853 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001854 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001855 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
1856 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001857 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1858 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
1859 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001860 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001861 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001862 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001863 surfaceFrame1->setAcquireFenceTime(26);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001864 mFrameTimeline->setSfWakeUp(sfToken1, 32, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001865 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1866 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1867 mFrameTimeline->setSfPresent(36, presentFence1);
1868 auto displayFrame1 = getDisplayFrame(0);
1869 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1870 presentFence1->signalForTest(40);
1871
1872 // Fences for the first frame haven't been flushed yet, so it should be 0
1873 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1874 auto actuals1 = presentedSurfaceFrame1.getActuals();
1875 EXPECT_EQ(actuals1.presentTime, 0);
1876
1877 // Trigger a flush by finalizing the next DisplayFrame
1878 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1879 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001880 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001881 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001882 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001883 surfaceFrame2->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001884 mFrameTimeline->setSfWakeUp(sfToken2, 43, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001885 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1886 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1887 mFrameTimeline->setSfPresent(56, presentFence2);
1888 auto displayFrame2 = getDisplayFrame(1);
1889 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1890
1891 // Fences for the first frame have flushed, so the present timestamps should be updated
1892 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
1893 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1894 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1895 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1896
1897 actuals1 = presentedSurfaceFrame1.getActuals();
1898 EXPECT_EQ(actuals1.presentTime, 40);
1899 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1900 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1901 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1902
1903 // Fences for the second frame haven't been flushed yet, so it should be 0
1904 presentFence2->signalForTest(60);
1905 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1906 auto actuals2 = presentedSurfaceFrame2.getActuals();
1907 EXPECT_EQ(actuals2.presentTime, 0);
1908
1909 addEmptyDisplayFrame();
1910
1911 // Fences for the second frame have flushed, so the present timestamps should be updated
1912 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
1913 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1914 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1915 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1916
1917 actuals2 = presentedSurfaceFrame2.getActuals();
1918 EXPECT_EQ(actuals2.presentTime, 60);
1919 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1920 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001921 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
1922 JankType::SurfaceFlingerCpuDeadlineMissed | JankType::AppDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001923}
1924
1925TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001926 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001927 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001928 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1929 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
1930 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
1931
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001932 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
1933 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001934 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001935 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001936 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001937 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001938 surfaceFrame1->setAcquireFenceTime(50);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001939 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001940 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1941 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1942 mFrameTimeline->setSfPresent(56, presentFence1);
1943 auto displayFrame1 = getDisplayFrame(0);
1944 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1945 presentFence1->signalForTest(60);
1946
1947 // Fences for the first frame haven't been flushed yet, so it should be 0
1948 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1949 auto actuals1 = presentedSurfaceFrame1.getActuals();
1950 EXPECT_EQ(actuals1.presentTime, 0);
1951
1952 // Trigger a flush by finalizing the next DisplayFrame
1953 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1954 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001955 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001956 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001957 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001958 surfaceFrame2->setAcquireFenceTime(84);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001959 mFrameTimeline->setSfWakeUp(sfToken2, 112, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001960 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
1961 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1962 mFrameTimeline->setSfPresent(116, presentFence2);
1963 auto displayFrame2 = getDisplayFrame(1);
1964 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1965 presentFence2->signalForTest(120);
1966
1967 // Fences for the first frame have flushed, so the present timestamps should be updated
1968 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
1969 actuals1 = presentedSurfaceFrame1.getActuals();
1970 EXPECT_EQ(actuals1.endTime, 50);
1971 EXPECT_EQ(actuals1.presentTime, 60);
1972
1973 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1974 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1975 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1976
1977 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1978 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1979 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1980
1981 // Fences for the second frame haven't been flushed yet, so it should be 0
1982 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1983 auto actuals2 = presentedSurfaceFrame2.getActuals();
1984 EXPECT_EQ(actuals2.presentTime, 0);
1985
1986 addEmptyDisplayFrame();
1987
1988 // Fences for the second frame have flushed, so the present timestamps should be updated
1989 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1990 actuals2 = presentedSurfaceFrame2.getActuals();
1991 EXPECT_EQ(actuals2.presentTime, 120);
1992
1993 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1994 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1995 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
1996
1997 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1998 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1999 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
2000 JankType::AppDeadlineMissed | JankType::BufferStuffing);
2001}
Alec Mouriadebf5c2021-01-05 12:57:36 -08002002
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002003TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
2004 // Layer specific increment
2005 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
2006 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2007 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2008 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2009
2010 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2011 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
2012 auto surfaceFrame1 =
2013 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
2014 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002015 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002016 surfaceFrame1->setAcquireFenceTime(50);
2017 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
2018 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2019 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2020 mFrameTimeline->setSfPresent(56, presentFence1);
2021 auto displayFrame1 = getDisplayFrame(0);
2022 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2023 presentFence1->signalForTest(60);
2024
2025 // Fences for the first frame haven't been flushed yet, so it should be 0
2026 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2027 auto actuals1 = presentedSurfaceFrame1.getActuals();
2028 EXPECT_EQ(actuals1.presentTime, 0);
2029
2030 // Trigger a flush by finalizing the next DisplayFrame
2031 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2032 auto surfaceFrame2 =
2033 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
2034 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002035 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002036 surfaceFrame2->setAcquireFenceTime(80);
2037 mFrameTimeline->setSfWakeUp(sfToken2, 82, Fps::fromPeriodNsecs(30));
2038 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
2039 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2040 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2041 mFrameTimeline->setSfPresent(86, presentFence2);
2042 auto displayFrame2 = getDisplayFrame(1);
2043 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2044 presentFence2->signalForTest(90);
2045
2046 // Fences for the first frame have flushed, so the present timestamps should be updated
2047 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2048 actuals1 = presentedSurfaceFrame1.getActuals();
2049 EXPECT_EQ(actuals1.endTime, 50);
2050 EXPECT_EQ(actuals1.presentTime, 60);
2051
2052 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2053 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2054 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2055
2056 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2057 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2058 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2059
2060 // Fences for the second frame haven't been flushed yet, so it should be 0
2061 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2062 auto actuals2 = presentedSurfaceFrame2.getActuals();
2063 EXPECT_EQ(actuals2.presentTime, 0);
2064
2065 addEmptyDisplayFrame();
2066
2067 // Fences for the second frame have flushed, so the present timestamps should be updated
2068 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2069 actuals2 = presentedSurfaceFrame2.getActuals();
2070 EXPECT_EQ(actuals2.presentTime, 90);
2071
2072 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2073 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2074 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
2075
2076 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2077 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2078 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
2079}
2080
Alec Mouriadebf5c2021-01-05 12:57:36 -08002081TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
2082 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
2083}
2084
2085TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002086 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002087
2088 auto surfaceFrame1 =
2089 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002090 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002091 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002092 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2093 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2094 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2095 presentFence1->signalForTest(oneHundredMs);
2096 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2097
2098 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2099}
2100
2101TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002102 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2103 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002104 auto surfaceFrame1 =
2105 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002106 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002107 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002108 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2109 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2110 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2111 presentFence1->signalForTest(oneHundredMs);
2112 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2113
2114 auto surfaceFrame2 =
2115 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002116 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002117 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002118 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2119 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2120 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2121 presentFence2->signalForTest(twoHundredMs);
2122 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2123
2124 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
2125}
2126
2127TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002128 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2129 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002130 auto surfaceFrame1 =
2131 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002132 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002133 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002134 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2135 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2136 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2137 presentFence1->signalForTest(oneHundredMs);
2138 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2139
2140 auto surfaceFrame2 =
2141 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002142 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002143 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002144 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2145 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2146 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2147 presentFence2->signalForTest(twoHundredMs);
2148 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2149
2150 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
2151}
2152
2153TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002154 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2155 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002156 auto surfaceFrame1 =
2157 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002158 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002159 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002160 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2161 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2162 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2163 presentFence1->signalForTest(oneHundredMs);
2164 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2165
2166 auto surfaceFrame2 =
2167 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002168 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002169 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002170 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2171 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2172 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2173 presentFence2->signalForTest(twoHundredMs);
2174 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2175
2176 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2177}
2178
2179TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002180 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2181 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2182 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2183 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2184 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002185 auto surfaceFrame1 =
2186 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002187 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002188 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002189 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2190 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2191 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2192 presentFence1->signalForTest(oneHundredMs);
2193 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2194
2195 auto surfaceFrame2 =
2196 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002197 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002198 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002199 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2200 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2201 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2202 presentFence2->signalForTest(twoHundredMs);
2203 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2204
2205 auto surfaceFrame3 =
2206 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002207 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002208 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002209 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2210 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2211 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2212 presentFence3->signalForTest(threeHundredMs);
2213 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2214
2215 auto surfaceFrame4 =
2216 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002217 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002218 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002219 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2220 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2221 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2222 presentFence4->signalForTest(fiveHundredMs);
2223 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2224
2225 auto surfaceFrame5 =
2226 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002227 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002228 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002229 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2230 // Dropped frames will be excluded from fps computation
2231 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2232 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2233 presentFence5->signalForTest(sixHundredMs);
2234 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2235
2236 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2237}
2238
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002239} // namespace android::frametimeline