blob: 71a567a23f93155fd5276b8c256a23c37113607e [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();
163 static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(2ns).count();
164 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";
172static constexpr const uid_t sUidOne = 0;
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700173static constexpr pid_t sPidOne = 10;
174static constexpr pid_t sPidTwo = 20;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000175static constexpr int32_t sInputEventId = 5;
Alec Mouriadebf5c2021-01-05 12:57:36 -0800176static constexpr int32_t sLayerIdOne = 1;
177static constexpr int32_t sLayerIdTwo = 2;
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000178static constexpr int32_t sGameMode = 0;
Alec Mouri9a29e672020-09-14 12:39:14 -0700179
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700180TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
181 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000182 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000183 flushTokens();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700184 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
185 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
186
187 // token1 should have expired
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700188 EXPECT_EQ(predictions.has_value(), false);
189
190 predictions = mTokenManager->getPredictionsForToken(token2);
191 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
192}
193
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700194TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800195 auto surfaceFrame1 =
196 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000197 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000198 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -0800199 auto surfaceFrame2 =
200 mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000201 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000202 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700203 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
204 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
205}
206
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700207TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800208 auto surfaceFrame =
209 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000210 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000211 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700212 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
213}
214
215TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
216 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000217 flushTokens();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000218 auto surfaceFrame =
219 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000220 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000221 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700222
223 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
224}
225
226TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
227 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000228 auto surfaceFrame =
229 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000230 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000231 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700232
233 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
234 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
235}
236
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000237TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
238 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
239 constexpr int32_t inputEventId = 1;
240 auto surfaceFrame =
241 mFrameTimeline->createSurfaceFrameForToken({token1, inputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000242 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000243 /*isBuffer*/ true, sGameMode);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000244
245 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
246}
247
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700248TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
249 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700250 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000251 auto surfaceFrame1 =
252 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000253 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000254 /*isBuffer*/ true, sGameMode);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700255
256 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800257 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000258 surfaceFrame1->setDropTime(12);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800259 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
260 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700261 mFrameTimeline->setSfPresent(25, presentFence1);
262 presentFence1->signalForTest(30);
263
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000264 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700265
266 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
267 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000268 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
269 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700270 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
271}
272
273TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800274 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800275 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700276 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
277 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700278 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri9a29e672020-09-14 12:39:14 -0700279 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000280 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800281 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000282 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Alec Mouri9a29e672020-09-14 12:39:14 -0700283 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000284 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800285 sUidOne, sLayerIdTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000286 sLayerNameTwo, /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800287 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800288 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
289 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
290 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
291 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700292 mFrameTimeline->setSfPresent(26, presentFence1);
293 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800294 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
295 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700296 presentFence1->signalForTest(42);
297
298 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800299 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700300 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
301 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
302
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000303 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700304
305 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800306 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700307 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
308 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100309 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
310 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700311}
312
313TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
314 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
315 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800316 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800317 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800318 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700319 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700320 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
321 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
322 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
323 int64_t sfToken = mTokenManager->generateTokenForPredictions(
324 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700325 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000326 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId},
Alec Mouriadebf5c2021-01-05 12:57:36 -0800327 sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000328 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000329 /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800330 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800331 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
332 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700333 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
334 presentFence->signalForTest(32 + frameTimeFactor);
335 frameTimeFactor += 30;
336 }
337 auto displayFrame0 = getDisplayFrame(0);
338
339 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800340 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700341
342 // Add one more display frame
343 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
344 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
345 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
346 int64_t sfToken = mTokenManager->generateTokenForPredictions(
347 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700348 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000349 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800350 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000351 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800352 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800353 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
354 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700355 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
356 presentFence->signalForTest(32 + frameTimeFactor);
357 displayFrame0 = getDisplayFrame(0);
358
359 // The window should have slided by 1 now and the previous 0th display frame
360 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800361 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700362}
363
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700364TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000365 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
366 "acquireFenceAfterQueue",
367 "acquireFenceAfterQueue",
368 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700369 surfaceFrame->setActualQueueTime(123);
370 surfaceFrame->setAcquireFenceTime(456);
371 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
372}
373
374TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000375 auto surfaceFrame = mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
376 "acquireFenceAfterQueue",
377 "acquireFenceAfterQueue",
378 /*isBuffer*/ true, sGameMode);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700379 surfaceFrame->setActualQueueTime(456);
380 surfaceFrame->setAcquireFenceTime(123);
381 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
382}
383
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700384TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
385 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
386 presentFence->signalForTest(2);
387
388 // Size shouldn't exceed maxDisplayFrames - 64
389 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700390 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800391 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000392 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000393 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700394 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800395 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800396 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
397 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700398 mFrameTimeline->setSfPresent(27, presentFence);
399 }
400 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
401
402 // Increase the size to 256
403 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000404 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700405
406 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700407 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800408 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000409 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000410 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700411 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800412 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800413 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
414 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700415 mFrameTimeline->setSfPresent(27, presentFence);
416 }
417 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
418
419 // Shrink the size to 128
420 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000421 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700422
423 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700424 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800425 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000426 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000427 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700428 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800429 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800430 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
431 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700432 mFrameTimeline->setSfPresent(27, presentFence);
433 }
434 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
435}
Alec Mouri9a29e672020-09-14 12:39:14 -0700436
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000437TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
438 Fps refreshRate = Fps::fromPeriodNsecs(11);
439
440 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
441 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
442 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
443
444 auto surfaceFrame1 =
445 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
446 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000447 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000448 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
449 surfaceFrame1->setAcquireFenceTime(20);
450 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
451 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
452
453 mFrameTimeline->setSfPresent(59, presentFence1);
454 presentFence1->signalForTest(-1);
455 addEmptyDisplayFrame();
456
457 auto displayFrame0 = getDisplayFrame(0);
458 EXPECT_EQ(displayFrame0->getActuals().presentTime, -1);
459 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown);
460 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
461 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
462}
463
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800464// Tests related to TimeStats
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000465TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
466 Fps refreshRate = Fps::fromPeriodNsecs(11);
467 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
468 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
469 int64_t surfaceFrameToken1 = -1;
470 int64_t sfToken1 = -1;
471
472 auto surfaceFrame1 =
473 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
474 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000475 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000476 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
477 surfaceFrame1->setAcquireFenceTime(20);
478 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
479 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
480 presentFence1->signalForTest(70);
481
482 mFrameTimeline->setSfPresent(59, presentFence1);
483}
484
Alec Mouri9a29e672020-09-14 12:39:14 -0700485TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000486 Fps refreshRate = Fps::fromPeriodNsecs(11);
Alec Mouri9a29e672020-09-14 12:39:14 -0700487 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800488 incrementJankyFrames(
489 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000490 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000491 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800492 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700493 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000494 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
495 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
496
Alec Mouri9a29e672020-09-14 12:39:14 -0700497 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000498 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800499 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000500 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000501 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
502 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800503 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
504 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000505 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700506
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000507 mFrameTimeline->setSfPresent(62, presentFence1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700508}
509
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000510TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfGpu) {
511 Fps refreshRate = Fps::fromPeriodNsecs(11);
512 EXPECT_CALL(*mTimeStats,
513 incrementJankyFrames(
514 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000515 sLayerNameOne, sGameMode,
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000516 JankType::SurfaceFlingerGpuDeadlineMissed, 4, 10,
517 0}));
518 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
519 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
520 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
521 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
522
523 auto surfaceFrame1 =
524 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
525 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000526 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000527 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
528 surfaceFrame1->setAcquireFenceTime(20);
529 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
530 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
531 gpuFence1->signalForTest(64);
532 presentFence1->signalForTest(70);
533
534 mFrameTimeline->setSfPresent(59, presentFence1, gpuFence1);
535}
536
Alec Mouri9a29e672020-09-14 12:39:14 -0700537TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800538 Fps refreshRate = Fps::fromPeriodNsecs(30);
Alec Mouri9a29e672020-09-14 12:39:14 -0700539 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800540 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000541 sLayerNameOne, sGameMode,
542 JankType::DisplayHAL, -4, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800543
Alec Mouri9a29e672020-09-14 12:39:14 -0700544 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000545 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
546 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
547
Alec Mouri9a29e672020-09-14 12:39:14 -0700548 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000549 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800550 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000551 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000552 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800553 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000554 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800555 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000556 presentFence1->signalForTest(90);
557 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800558 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700559}
560
561TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800562 Fps refreshRate = Fps(11.0);
Alec Mouri9a29e672020-09-14 12:39:14 -0700563 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000564 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000565 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000566 JankType::AppDeadlineMissed, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000567 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700568 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000569 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
570 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
571
Alec Mouri9a29e672020-09-14 12:39:14 -0700572 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000573 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800574 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000575 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000576 surfaceFrame1->setAcquireFenceTime(45);
577 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700578
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800579 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
580 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000581 presentFence1->signalForTest(90);
582 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100583
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800584 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700585}
586
Adithya Srinivasanead17162021-02-18 02:17:37 +0000587TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000588 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000589 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000590 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000591 sLayerNameOne, sGameMode,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000592 JankType::SurfaceFlingerScheduling,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000593 -4, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000594 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000595 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
596 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
597
Adithya Srinivasanead17162021-02-18 02:17:37 +0000598 auto surfaceFrame1 =
599 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800600 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000601 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000602 surfaceFrame1->setAcquireFenceTime(50);
603 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000604
605 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
606 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000607 presentFence1->signalForTest(60);
608 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000609
610 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
611}
612
613TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000614 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000615 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000616 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000617 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000618 JankType::PredictionError, -4, 5,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000619 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000620 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000621 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
622 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
623
Adithya Srinivasanead17162021-02-18 02:17:37 +0000624 auto surfaceFrame1 =
625 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800626 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000627 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000628 surfaceFrame1->setAcquireFenceTime(40);
629 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000630
631 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
632 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000633 presentFence1->signalForTest(65);
634 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000635
636 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
637}
638
639TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000640 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000641 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000642 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000643 sLayerNameOne, sGameMode,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000644 JankType::BufferStuffing, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000645 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000646 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000647 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
648 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
649
Adithya Srinivasanead17162021-02-18 02:17:37 +0000650 auto surfaceFrame1 =
651 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800652 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000653 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000654 surfaceFrame1->setAcquireFenceTime(40);
655 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000656
657 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000658 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000659 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000660 presentFence1->signalForTest(90);
661 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000662
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000663 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000664}
665
Alec Mouri363faf02021-01-29 16:34:55 -0800666TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000667 Fps refreshRate = Fps::fromPeriodNsecs(11);
668 Fps renderRate = Fps::fromPeriodNsecs(30);
Alec Mouri363faf02021-01-29 16:34:55 -0800669 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000670 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne,
671 sLayerNameOne, sGameMode,
672 JankType::AppDeadlineMissed, -4, 0,
673 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800674 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000675 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
676 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
677
Alec Mouri363faf02021-01-29 16:34:55 -0800678 auto surfaceFrame1 =
679 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800680 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000681 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000682 surfaceFrame1->setAcquireFenceTime(45);
683 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800684
685 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
686 surfaceFrame1->setRenderRate(renderRate);
687 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000688 presentFence1->signalForTest(90);
689 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800690
691 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
692}
693
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000694TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
695 Fps refreshRate = Fps::fromPeriodNsecs(11);
696 Fps renderRate = Fps::fromPeriodNsecs(30);
697
698 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000699 incrementJankyFrames(
700 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000701 sGameMode,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000702 JankType::Unknown | JankType::AppDeadlineMissed,
Adithya Srinivasande272452021-04-10 00:21:00 +0000703 0, 0, 25}));
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000704 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
705 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
706 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
707
708 auto surfaceFrame1 =
709 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
710 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000711 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000712 surfaceFrame1->setAcquireFenceTime(45);
713 // Trigger a prediction expiry
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000714 flushTokens();
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000715 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
716
717 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
718 surfaceFrame1->setRenderRate(renderRate);
719 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
720 presentFence1->signalForTest(90);
721 mFrameTimeline->setSfPresent(86, presentFence1);
722
723 auto displayFrame = getDisplayFrame(0);
724 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
725 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
726 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
727 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
728
729 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000730 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000731}
732
Adithya Srinivasan01189672020-10-20 14:23:05 -0700733/*
734 * Tracing Tests
735 *
736 * Trace packets are flushed all the way only when the next packet is traced.
737 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
738 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
739 * will have additional empty frames created for this reason.
740 */
741TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
742 auto tracingSession = getTracingSessionForTest();
743 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700744 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000745 auto surfaceFrame1 =
746 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000747 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000748 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700749
750 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800751 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800752 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
753 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700754 mFrameTimeline->setSfPresent(25, presentFence1);
755 presentFence1->signalForTest(30);
756
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000757 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700758
759 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000760 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700761}
762
763TEST_F(FrameTimelineTest, tracing_sanityTest) {
764 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800765 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800766 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700767 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700768
769 tracingSession->StartBlocking();
770 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
771 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000772 auto surfaceFrame1 =
773 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000774 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000775 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700776
777 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800778 mFrameTimeline->setSfWakeUp(token2, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800779 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
780 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700781 mFrameTimeline->setSfPresent(25, presentFence1);
782 presentFence1->signalForTest(30);
783
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000784 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000785 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700786 tracingSession->StopBlocking();
787
788 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000789 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000790 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700791}
792
793TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
794 auto tracingSession = getTracingSessionForTest();
795 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700796
797 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700798
799 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800800 mFrameTimeline->setSfWakeUp(-1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700801 mFrameTimeline->setSfPresent(25, presentFence1);
802 presentFence1->signalForTest(30);
803
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000804 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000805 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700806 tracingSession->StopBlocking();
807
808 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000809 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700810}
811
812TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
813 auto tracingSession = getTracingSessionForTest();
814 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700815
816 tracingSession->StartBlocking();
817 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -0800818 auto surfaceFrame1 =
819 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000820 sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +0000821 /*isBuffer*/ true, sGameMode);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700822
823 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800824 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800825 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
826 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700827 mFrameTimeline->setSfPresent(25, presentFence1);
828 presentFence1->signalForTest(30);
829
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000830 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000831 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700832 tracingSession->StopBlocking();
833
834 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000835 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
836 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000837 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700838}
839
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000840ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
841 pid_t pid) {
842 ProtoExpectedDisplayFrameStart proto;
843 proto.set_cookie(cookie);
844 proto.set_token(token);
845 proto.set_pid(pid);
846 return proto;
847}
848
849ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
850 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000851 bool gpuComposition, ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000852 ProtoActualDisplayFrameStart proto;
853 proto.set_cookie(cookie);
854 proto.set_token(token);
855 proto.set_pid(pid);
856 proto.set_present_type(presentType);
857 proto.set_on_time_finish(onTimeFinish);
858 proto.set_gpu_composition(gpuComposition);
859 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000860 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000861 return proto;
862}
863
864ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
865 int64_t displayFrameToken,
866 pid_t pid,
867 std::string layerName) {
868 ProtoExpectedSurfaceFrameStart proto;
869 proto.set_cookie(cookie);
870 proto.set_token(token);
871 proto.set_display_frame_token(displayFrameToken);
872 proto.set_pid(pid);
873 proto.set_layer_name(layerName);
874 return proto;
875}
876
877ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
878 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
879 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000880 ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000881 ProtoActualSurfaceFrameStart proto;
882 proto.set_cookie(cookie);
883 proto.set_token(token);
884 proto.set_display_frame_token(displayFrameToken);
885 proto.set_pid(pid);
886 proto.set_layer_name(layerName);
887 proto.set_present_type(presentType);
888 proto.set_on_time_finish(onTimeFinish);
889 proto.set_gpu_composition(gpuComposition);
890 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000891 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000892 return proto;
893}
894
895ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
896 ProtoFrameEnd proto;
897 proto.set_cookie(cookie);
898 return proto;
899}
900
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000901void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
902 const ProtoExpectedDisplayFrameStart& source) {
903 ASSERT_TRUE(received.has_cookie());
904 EXPECT_EQ(received.cookie(), source.cookie());
905
Adithya Srinivasan01189672020-10-20 14:23:05 -0700906 ASSERT_TRUE(received.has_token());
907 EXPECT_EQ(received.token(), source.token());
908
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000909 ASSERT_TRUE(received.has_pid());
910 EXPECT_EQ(received.pid(), source.pid());
911}
912
913void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
914 const ProtoActualDisplayFrameStart& source) {
915 ASSERT_TRUE(received.has_cookie());
916 EXPECT_EQ(received.cookie(), source.cookie());
917
918 ASSERT_TRUE(received.has_token());
919 EXPECT_EQ(received.token(), source.token());
920
921 ASSERT_TRUE(received.has_pid());
922 EXPECT_EQ(received.pid(), source.pid());
923
Adithya Srinivasan01189672020-10-20 14:23:05 -0700924 ASSERT_TRUE(received.has_present_type());
925 EXPECT_EQ(received.present_type(), source.present_type());
926 ASSERT_TRUE(received.has_on_time_finish());
927 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
928 ASSERT_TRUE(received.has_gpu_composition());
929 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
930 ASSERT_TRUE(received.has_jank_type());
931 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000932 ASSERT_TRUE(received.has_prediction_type());
933 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700934}
935
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000936void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
937 const ProtoExpectedSurfaceFrameStart& source) {
938 ASSERT_TRUE(received.has_cookie());
939 EXPECT_EQ(received.cookie(), source.cookie());
940
Adithya Srinivasan01189672020-10-20 14:23:05 -0700941 ASSERT_TRUE(received.has_token());
942 EXPECT_EQ(received.token(), source.token());
943
944 ASSERT_TRUE(received.has_display_frame_token());
945 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
946
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000947 ASSERT_TRUE(received.has_pid());
948 EXPECT_EQ(received.pid(), source.pid());
949
950 ASSERT_TRUE(received.has_layer_name());
951 EXPECT_EQ(received.layer_name(), source.layer_name());
952}
953
954void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
955 const ProtoActualSurfaceFrameStart& source) {
956 ASSERT_TRUE(received.has_cookie());
957 EXPECT_EQ(received.cookie(), source.cookie());
958
959 ASSERT_TRUE(received.has_token());
960 EXPECT_EQ(received.token(), source.token());
961
962 ASSERT_TRUE(received.has_display_frame_token());
963 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
964
965 ASSERT_TRUE(received.has_pid());
966 EXPECT_EQ(received.pid(), source.pid());
967
968 ASSERT_TRUE(received.has_layer_name());
969 EXPECT_EQ(received.layer_name(), source.layer_name());
970
Adithya Srinivasan01189672020-10-20 14:23:05 -0700971 ASSERT_TRUE(received.has_present_type());
972 EXPECT_EQ(received.present_type(), source.present_type());
973 ASSERT_TRUE(received.has_on_time_finish());
974 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
975 ASSERT_TRUE(received.has_gpu_composition());
976 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
977 ASSERT_TRUE(received.has_jank_type());
978 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000979 ASSERT_TRUE(received.has_prediction_type());
980 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000981}
Adithya Srinivasan01189672020-10-20 14:23:05 -0700982
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000983void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
984 ASSERT_TRUE(received.has_cookie());
985 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700986}
987
988TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
989 auto tracingSession = getTracingSessionForTest();
990 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700991
992 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000993 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -0700994
995 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800996 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700997 mFrameTimeline->setSfPresent(26, presentFence1);
998 presentFence1->signalForTest(31);
999
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001000 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001001 auto protoExpectedDisplayFrameStart =
1002 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1003 kSurfaceFlingerPid);
1004 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1005 auto protoActualDisplayFrameStart =
1006 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
1007 kSurfaceFlingerPid,
1008 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001009 FrameTimelineEvent::JANK_NONE,
1010 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001011 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001012
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001013 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001014 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001015 tracingSession->StopBlocking();
1016
1017 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001018 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001019
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001020 // Packet - 0 : ExpectedDisplayFrameStart
1021 const auto& packet0 = packets[0];
1022 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001023 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001024 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001025
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001026 const auto& event0 = packet0.frame_timeline_event();
1027 ASSERT_TRUE(event0.has_expected_display_frame_start());
1028 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
1029 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
1030
1031 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
1032 const auto& packet1 = packets[1];
1033 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001034 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001035 ASSERT_TRUE(packet1.has_frame_timeline_event());
1036
1037 const auto& event1 = packet1.frame_timeline_event();
1038 ASSERT_TRUE(event1.has_frame_end());
1039 const auto& expectedDisplayFrameEnd = event1.frame_end();
1040 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
1041
1042 // Packet - 2 : ActualDisplayFrameStart
1043 const auto& packet2 = packets[2];
1044 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001045 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001046 ASSERT_TRUE(packet2.has_frame_timeline_event());
1047
1048 const auto& event2 = packet2.frame_timeline_event();
1049 ASSERT_TRUE(event2.has_actual_display_frame_start());
1050 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1051 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1052
1053 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1054 const auto& packet3 = packets[3];
1055 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001056 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001057 ASSERT_TRUE(packet3.has_frame_timeline_event());
1058
1059 const auto& event3 = packet3.frame_timeline_event();
1060 ASSERT_TRUE(event3.has_frame_end());
1061 const auto& actualDisplayFrameEnd = event3.frame_end();
1062 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001063}
1064
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001065TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1066 auto tracingSession = getTracingSessionForTest();
1067 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1068
1069 tracingSession->StartBlocking();
1070 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1071 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001072 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001073
1074 // Set up the display frame
1075 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
1076 mFrameTimeline->setSfPresent(26, presentFence1);
1077 presentFence1->signalForTest(31);
1078
1079 int64_t traceCookie = snoopCurrentTraceCookie();
1080
1081 auto protoActualDisplayFrameStart =
1082 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1083 kSurfaceFlingerPid,
1084 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001085 false, FrameTimelineEvent::JANK_UNKNOWN,
1086 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001087 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1088
1089 addEmptyDisplayFrame();
1090 flushTrace();
1091 tracingSession->StopBlocking();
1092
1093 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1094 // Only actual timeline packets should be in the trace
1095 EXPECT_EQ(packets.size(), 2u);
1096
1097 // Packet - 0 : ActualDisplayFrameStart
1098 const auto& packet0 = packets[0];
1099 ASSERT_TRUE(packet0.has_timestamp());
1100 EXPECT_EQ(packet0.timestamp(), 20u);
1101 ASSERT_TRUE(packet0.has_frame_timeline_event());
1102
1103 const auto& event0 = packet0.frame_timeline_event();
1104 ASSERT_TRUE(event0.has_actual_display_frame_start());
1105 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1106 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1107
1108 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1109 const auto& packet1 = packets[1];
1110 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001111 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001112 ASSERT_TRUE(packet1.has_frame_timeline_event());
1113
1114 const auto& event1 = packet1.frame_timeline_event();
1115 ASSERT_TRUE(event1.has_frame_end());
1116 const auto& actualDisplayFrameEnd = event1.frame_end();
1117 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1118}
1119
Adithya Srinivasan01189672020-10-20 14:23:05 -07001120TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1121 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001122 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001123 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -07001124 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1125 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1126
1127 tracingSession->StartBlocking();
1128 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1129 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001130
1131 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001132 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001133 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001134 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001135 auto surfaceFrame2 =
1136 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 surfaceFrame1->setActualQueueTime(10);
1140 surfaceFrame1->setDropTime(15);
1141
1142 surfaceFrame2->setActualQueueTime(15);
1143 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001144
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001145 // First 2 cookies will be used by the DisplayFrame
1146 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1147
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001148 auto protoDroppedSurfaceFrameExpectedStart =
1149 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1150 displayFrameToken1, sPidOne, sLayerNameOne);
1151 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1152 auto protoDroppedSurfaceFrameActualStart =
1153 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1154 displayFrameToken1, sPidOne, sLayerNameOne,
1155 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001156 FrameTimelineEvent::JANK_NONE,
1157 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001158 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001159
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001160 auto protoPresentedSurfaceFrameExpectedStart =
1161 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1162 displayFrameToken1, sPidOne, sLayerNameOne);
1163 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1164 auto protoPresentedSurfaceFrameActualStart =
1165 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1166 displayFrameToken1, sPidOne, sLayerNameOne,
1167 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001168 FrameTimelineEvent::JANK_NONE,
1169 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001170 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001171
1172 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -08001173 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001174 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1175 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001176 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001177 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001178 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001179 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001180
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001181 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001182 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001183 tracingSession->StopBlocking();
1184
1185 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001186 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1187 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001188
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001189 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001190 const auto& packet4 = packets[4];
1191 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001192 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001193 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001194
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001195 const auto& event4 = packet4.frame_timeline_event();
1196 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001197 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1198 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001199
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001200 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001201 const auto& packet5 = packets[5];
1202 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001203 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001204 ASSERT_TRUE(packet5.has_frame_timeline_event());
1205
1206 const auto& event5 = packet5.frame_timeline_event();
1207 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001208 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1209 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001210
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001211 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001212 const auto& packet6 = packets[6];
1213 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001214 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001215 ASSERT_TRUE(packet6.has_frame_timeline_event());
1216
1217 const auto& event6 = packet6.frame_timeline_event();
1218 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001219 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1220 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001221
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001222 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001223 const auto& packet7 = packets[7];
1224 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001225 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001226 ASSERT_TRUE(packet7.has_frame_timeline_event());
1227
1228 const auto& event7 = packet7.frame_timeline_event();
1229 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001230 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1231 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1232
1233 // Packet - 8 : ExpectedSurfaceFrameStart2
1234 const auto& packet8 = packets[8];
1235 ASSERT_TRUE(packet8.has_timestamp());
1236 EXPECT_EQ(packet8.timestamp(), 10u);
1237 ASSERT_TRUE(packet8.has_frame_timeline_event());
1238
1239 const auto& event8 = packet8.frame_timeline_event();
1240 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1241 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1242 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1243
1244 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1245 const auto& packet9 = packets[9];
1246 ASSERT_TRUE(packet9.has_timestamp());
1247 EXPECT_EQ(packet9.timestamp(), 25u);
1248 ASSERT_TRUE(packet9.has_frame_timeline_event());
1249
1250 const auto& event9 = packet9.frame_timeline_event();
1251 ASSERT_TRUE(event9.has_frame_end());
1252 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1253 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1254
1255 // Packet - 10 : ActualSurfaceFrameStart2
1256 const auto& packet10 = packets[10];
1257 ASSERT_TRUE(packet10.has_timestamp());
1258 EXPECT_EQ(packet10.timestamp(), 10u);
1259 ASSERT_TRUE(packet10.has_frame_timeline_event());
1260
1261 const auto& event10 = packet10.frame_timeline_event();
1262 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1263 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1264 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1265
1266 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1267 const auto& packet11 = packets[11];
1268 ASSERT_TRUE(packet11.has_timestamp());
1269 EXPECT_EQ(packet11.timestamp(), 20u);
1270 ASSERT_TRUE(packet11.has_frame_timeline_event());
1271
1272 const auto& event11 = packet11.frame_timeline_event();
1273 ASSERT_TRUE(event11.has_frame_end());
1274 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1275 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1276}
1277
1278TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1279 auto tracingSession = getTracingSessionForTest();
1280 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1281
1282 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001283 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1284 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1285 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001286 int64_t surfaceFrameToken =
1287 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1288
1289 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001290 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001291 auto surfaceFrame1 =
1292 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0},
Alec Mouriadebf5c2021-01-05 12:57:36 -08001293 sPidOne, sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001294 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001295 surfaceFrame1->setActualQueueTime(appEndTime);
1296 surfaceFrame1->setAcquireFenceTime(appEndTime);
1297
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001298 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1299 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1300 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001301 int64_t displayFrameToken =
1302 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1303
1304 // First 2 cookies will be used by the DisplayFrame
1305 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1306
1307 auto protoActualSurfaceFrameStart =
1308 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1309 displayFrameToken, sPidOne, sLayerNameOne,
1310 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001311 false, FrameTimelineEvent::JANK_UNKNOWN,
1312 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001313 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1314
1315 // Set up the display frame
1316 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1317 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1318 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1319 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1320 presentFence1->signalForTest(sfPresentTime);
1321
1322 addEmptyDisplayFrame();
1323 flushTrace();
1324 tracingSession->StopBlocking();
1325
1326 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1327 // Display Frame 4 packets + SurfaceFrame 2 packets
1328 ASSERT_EQ(packets.size(), 6u);
1329
1330 // Packet - 4 : ActualSurfaceFrameStart
1331 const auto& packet4 = packets[4];
1332 ASSERT_TRUE(packet4.has_timestamp());
1333 EXPECT_EQ(packet4.timestamp(),
1334 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1335 ASSERT_TRUE(packet4.has_frame_timeline_event());
1336
1337 const auto& event4 = packet4.frame_timeline_event();
1338 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1339 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1340 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1341
1342 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1343 const auto& packet5 = packets[5];
1344 ASSERT_TRUE(packet5.has_timestamp());
1345 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1346 ASSERT_TRUE(packet5.has_frame_timeline_event());
1347
1348 const auto& event5 = packet5.frame_timeline_event();
1349 ASSERT_TRUE(event5.has_frame_end());
1350 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001351 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001352}
1353
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001354TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDroppedFramesTracedProperly) {
1355 auto tracingSession = getTracingSessionForTest();
1356 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1357
1358 tracingSession->StartBlocking();
1359 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1360 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1361 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
1362 int64_t surfaceFrameToken =
1363 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1364
1365 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001366 flushTokens();
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001367 auto surfaceFrame1 =
1368 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0},
1369 sPidOne, sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001370 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001371
1372 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(22ms).count();
1373 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1374 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
1375 int64_t displayFrameToken =
1376 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1377
1378 // First 2 cookies will be used by the DisplayFrame
1379 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1380
1381 auto protoActualSurfaceFrameStart =
1382 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1383 displayFrameToken, sPidOne, sLayerNameOne,
1384 FrameTimelineEvent::PRESENT_DROPPED, false, false,
1385 FrameTimelineEvent::JANK_NONE,
1386 FrameTimelineEvent::PREDICTION_EXPIRED);
1387 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1388
1389 // Set up the display frame
1390 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1391 surfaceFrame1->setDropTime(sfStartTime);
1392 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1393 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1394 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1395 presentFence1->signalForTest(sfPresentTime);
1396
1397 addEmptyDisplayFrame();
1398 flushTrace();
1399 tracingSession->StopBlocking();
1400
1401 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1402 // Display Frame 4 packets + SurfaceFrame 2 packets
1403 ASSERT_EQ(packets.size(), 6u);
1404
1405 // Packet - 4 : ActualSurfaceFrameStart
1406 const auto& packet4 = packets[4];
1407 ASSERT_TRUE(packet4.has_timestamp());
1408 EXPECT_EQ(packet4.timestamp(),
1409 static_cast<uint64_t>(sfStartTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1410 ASSERT_TRUE(packet4.has_frame_timeline_event());
1411
1412 const auto& event4 = packet4.frame_timeline_event();
1413 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1414 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1415 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1416
1417 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1418 const auto& packet5 = packets[5];
1419 ASSERT_TRUE(packet5.has_timestamp());
1420 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(sfStartTime));
1421 ASSERT_TRUE(packet5.has_frame_timeline_event());
1422
1423 const auto& event5 = packet5.frame_timeline_event();
1424 ASSERT_TRUE(event5.has_frame_end());
1425 const auto& actualSurfaceFrameEnd = event5.frame_end();
1426 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
1427}
1428
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001429// Tests for Jank classification
1430TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001431 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001432 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001433 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1434 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001435 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001436 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001437 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001438 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001439 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001440 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001441 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1442 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1443 mFrameTimeline->setSfPresent(26, presentFence1);
1444 auto displayFrame = getDisplayFrame(0);
1445 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1446 presentFence1->signalForTest(29);
1447
1448 // Fences haven't been flushed yet, so it should be 0
1449 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1450 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1451
1452 addEmptyDisplayFrame();
1453 displayFrame = getDisplayFrame(0);
1454
1455 // Fences have flushed, so the present timestamps should be updated
1456 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1457 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1458 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1459 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1460 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
1461}
1462
1463TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001464 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001465 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001466 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1467 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001468 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001469 mFrameTimeline->setSfPresent(26, presentFence1);
1470 auto displayFrame = getDisplayFrame(0);
1471 presentFence1->signalForTest(30);
1472
1473 // Fences for the first frame haven't been flushed yet, so it should be 0
1474 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1475
1476 // Trigger a flush by finalizing the next DisplayFrame
1477 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001478 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001479 mFrameTimeline->setSfPresent(56, presentFence2);
1480 displayFrame = getDisplayFrame(0);
1481
1482 // Fences for the first frame have flushed, so the present timestamps should be updated
1483 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1484 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1485 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1486 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1487
1488 // Fences for the second frame haven't been flushed yet, so it should be 0
1489 auto displayFrame2 = getDisplayFrame(1);
1490 presentFence2->signalForTest(65);
1491 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001492 addEmptyDisplayFrame();
1493 displayFrame2 = getDisplayFrame(1);
1494
1495 // Fences for the second frame have flushed, so the present timestamps should be updated
1496 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1497 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1498 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1499 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1500}
1501
1502TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001503 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001504 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001505 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1506 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001507 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001508 mFrameTimeline->setSfPresent(26, presentFence1);
1509 auto displayFrame = getDisplayFrame(0);
1510 presentFence1->signalForTest(50);
1511
1512 // Fences for the first frame haven't been flushed yet, so it should be 0
1513 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1514
1515 // Trigger a flush by finalizing the next DisplayFrame
1516 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001517 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001518 mFrameTimeline->setSfPresent(56, presentFence2);
1519 displayFrame = getDisplayFrame(0);
1520
1521 // Fences for the first frame have flushed, so the present timestamps should be updated
1522 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1523 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1524 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1525 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1526
1527 // Fences for the second frame haven't been flushed yet, so it should be 0
1528 auto displayFrame2 = getDisplayFrame(1);
1529 presentFence2->signalForTest(75);
1530 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1531
1532 addEmptyDisplayFrame();
1533 displayFrame2 = getDisplayFrame(1);
1534
1535 // Fences for the second frame have flushed, so the present timestamps should be updated
1536 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1537 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1538 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1539 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1540}
1541
1542TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001543 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1544 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001545 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001546
1547 mFrameTimeline->setSfPresent(22, presentFence1);
1548 auto displayFrame = getDisplayFrame(0);
1549 presentFence1->signalForTest(28);
1550
1551 // Fences haven't been flushed yet, so it should be 0
1552 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1553
1554 addEmptyDisplayFrame();
1555 displayFrame = getDisplayFrame(0);
1556
1557 // Fences have flushed, so the present timestamps should be updated
1558 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1559 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1560 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1561 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1562}
1563
1564TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001565 /*
1566 * Case 1 - cpu time > vsync period but combined time > deadline > deadline -> cpudeadlinemissed
1567 * Case 2 - cpu time < vsync period but combined time > deadline -> gpudeadlinemissed
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001568 * Case 3 - previous frame ran longer -> sf_stuffing
1569 * Case 4 - Long cpu under SF stuffing -> cpudeadlinemissed
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001570 */
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001571 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001572 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001573 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1574 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001575 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1576 auto gpuFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001577 auto gpuFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1578 auto gpuFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001579 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001580 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001581 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1582 int64_t sfToken4 = mTokenManager->generateTokenForPredictions({112, 120, 120});
1583
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001584 // case 1 - cpu time = 33 - 12 = 21, vsync period = 11
Alec Mouri7d436ec2021-01-27 20:40:50 -08001585 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001586 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
1587 auto displayFrame0 = getDisplayFrame(0);
1588 gpuFence1->signalForTest(36);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001589 presentFence1->signalForTest(52);
1590
1591 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001592 EXPECT_EQ(displayFrame0->getActuals().presentTime, 0);
1593
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001594 // case 2 - cpu time = 56 - 52 = 4, vsync period = 30
1595 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001596 mFrameTimeline->setSfPresent(56, presentFence2, gpuFence2);
1597 auto displayFrame1 = getDisplayFrame(1);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001598 gpuFence2->signalForTest(76);
1599 presentFence2->signalForTest(90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001600
1601 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1602 // Fences have flushed for first displayFrame, so the present timestamps should be updated
1603 EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
1604 EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1605 EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1606 EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001607
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001608 // case 3 - cpu time = 86 - 82 = 4, vsync period = 30
1609 mFrameTimeline->setSfWakeUp(sfToken3, 106, Fps::fromPeriodNsecs(30));
1610 mFrameTimeline->setSfPresent(112, presentFence3, gpuFence3);
1611 auto displayFrame2 = getDisplayFrame(2);
1612 gpuFence3->signalForTest(116);
1613 presentFence3->signalForTest(120);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001614
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001615 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001616 // Fences have flushed for second displayFrame, so the present timestamps should be updated
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001617 EXPECT_EQ(displayFrame1->getActuals().presentTime, 90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001618 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1619 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1620 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001621
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001622 // case 4 - cpu time = 86 - 82 = 4, vsync period = 30
1623 mFrameTimeline->setSfWakeUp(sfToken4, 120, Fps::fromPeriodNsecs(30));
1624 mFrameTimeline->setSfPresent(140, presentFence4, gpuFence4);
1625 auto displayFrame3 = getDisplayFrame(3);
1626 gpuFence4->signalForTest(156);
1627 presentFence4->signalForTest(180);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001628
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001629 EXPECT_EQ(displayFrame3->getActuals().presentTime, 0);
1630 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1631 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1632 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1633 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1634 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerStuffing);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001635
1636 addEmptyDisplayFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001637
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001638 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1639 EXPECT_EQ(displayFrame3->getActuals().presentTime, 180);
1640 EXPECT_EQ(displayFrame3->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1641 EXPECT_EQ(displayFrame3->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1642 EXPECT_EQ(displayFrame3->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001643}
1644
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001645TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001646 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001647 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001648 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1649 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001650 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1651 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1652 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001653 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001654 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001655 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001656 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001657 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001658 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1659 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001660 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001661 auto displayFrame1 = getDisplayFrame(0);
1662 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1663 presentFence1->signalForTest(30);
1664
1665 // Fences for the first frame haven't been flushed yet, so it should be 0
1666 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1667 auto actuals1 = presentedSurfaceFrame1.getActuals();
1668 EXPECT_EQ(actuals1.presentTime, 0);
1669
1670 // Trigger a flush by finalizing the next DisplayFrame
1671 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1672 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001673 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001674 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001675 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001676 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001677 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001678 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1679 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001680 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001681 auto displayFrame2 = getDisplayFrame(1);
1682 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1683
1684 // Fences for the first frame have flushed, so the present timestamps should be updated
1685 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1686 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1687 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1688 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1689
1690 actuals1 = presentedSurfaceFrame1.getActuals();
1691 EXPECT_EQ(actuals1.presentTime, 30);
1692 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1693 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1694 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1695
1696 // Fences for the second frame haven't been flushed yet, so it should be 0
1697 presentFence2->signalForTest(65);
1698 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1699 auto actuals2 = presentedSurfaceFrame2.getActuals();
1700 EXPECT_EQ(actuals2.presentTime, 0);
1701
Alec Mouri363faf02021-01-29 16:34:55 -08001702 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1703
1704 EXPECT_CALL(*mTimeStats,
1705 incrementJankyFrames(
1706 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001707 sLayerNameOne, sGameMode,
1708 JankType::PredictionError, -3, 5, 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08001709
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001710 addEmptyDisplayFrame();
1711
1712 // Fences for the second frame have flushed, so the present timestamps should be updated
1713 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1714 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1715 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1716 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1717
1718 actuals2 = presentedSurfaceFrame2.getActuals();
1719 EXPECT_EQ(actuals2.presentTime, 65);
1720 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1721 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1722 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1723}
1724
1725TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001726 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001727 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001728 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1729 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001730 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1731 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1732 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001733 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001734 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001735 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001736 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001737 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001738 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1739 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1740 mFrameTimeline->setSfPresent(26, presentFence1);
1741 auto displayFrame1 = getDisplayFrame(0);
1742 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1743 presentFence1->signalForTest(50);
1744
1745 // Fences for the first frame haven't been flushed yet, so it should be 0
1746 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1747 auto actuals1 = presentedSurfaceFrame1.getActuals();
1748 EXPECT_EQ(actuals1.presentTime, 0);
1749
1750 // Trigger a flush by finalizing the next DisplayFrame
1751 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1752 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001753 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001754 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001755 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001756 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001757 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001758 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1759 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001760 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001761 auto displayFrame2 = getDisplayFrame(1);
1762 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1763
1764 // Fences for the first frame have flushed, so the present timestamps should be updated
1765 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1766 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1767 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1768 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1769
1770 actuals1 = presentedSurfaceFrame1.getActuals();
1771 EXPECT_EQ(actuals1.presentTime, 50);
1772 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1773 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1774 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1775
1776 // Fences for the second frame haven't been flushed yet, so it should be 0
1777 presentFence2->signalForTest(86);
1778 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1779 auto actuals2 = presentedSurfaceFrame2.getActuals();
1780 EXPECT_EQ(actuals2.presentTime, 0);
1781
Alec Mouri363faf02021-01-29 16:34:55 -08001782 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1783
1784 EXPECT_CALL(*mTimeStats,
1785 incrementJankyFrames(
1786 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001787 sLayerNameOne, sGameMode,
1788 JankType::PredictionError, -3, 5, 0}));
Alec Mouri363faf02021-01-29 16:34:55 -08001789
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001790 addEmptyDisplayFrame();
1791
1792 // Fences for the second frame have flushed, so the present timestamps should be updated
1793 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1794 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1795 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1796 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1797
1798 actuals2 = presentedSurfaceFrame2.getActuals();
1799 EXPECT_EQ(actuals2.presentTime, 86);
1800 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1801 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1802 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1803}
1804
1805TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001806 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08001807
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001808 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001809 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001810 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
1811 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001812 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001813 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001814 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001815 surfaceFrame1->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001816 mFrameTimeline->setSfWakeUp(sfToken1, 42, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001817 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1818 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1819 mFrameTimeline->setSfPresent(46, presentFence1);
1820 auto displayFrame1 = getDisplayFrame(0);
1821 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1822 presentFence1->signalForTest(50);
1823
1824 // Fences for the first frame haven't been flushed yet, so it should be 0
1825 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1826 auto actuals1 = presentedSurfaceFrame1.getActuals();
1827 EXPECT_EQ(actuals1.presentTime, 0);
1828
1829 addEmptyDisplayFrame();
1830
1831 // Fences for the first frame have flushed, so the present timestamps should be updated
1832 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1833 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1834 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1835 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1836
1837 actuals1 = presentedSurfaceFrame1.getActuals();
1838 EXPECT_EQ(actuals1.presentTime, 50);
1839 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1840 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1841 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
1842}
1843
1844TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001845 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as only
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001846 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001847 // jank to the SurfaceFrame along with AppDeadlineMissed.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001848
Alec Mouri363faf02021-01-29 16:34:55 -08001849 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001850 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001851 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
1852 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001853 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1854 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
1855 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001856 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001857 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001858 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001859 surfaceFrame1->setAcquireFenceTime(26);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001860 mFrameTimeline->setSfWakeUp(sfToken1, 32, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001861 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1862 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1863 mFrameTimeline->setSfPresent(36, presentFence1);
1864 auto displayFrame1 = getDisplayFrame(0);
1865 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1866 presentFence1->signalForTest(40);
1867
1868 // Fences for the first frame haven't been flushed yet, so it should be 0
1869 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1870 auto actuals1 = presentedSurfaceFrame1.getActuals();
1871 EXPECT_EQ(actuals1.presentTime, 0);
1872
1873 // Trigger a flush by finalizing the next DisplayFrame
1874 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1875 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001876 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001877 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001878 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001879 surfaceFrame2->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001880 mFrameTimeline->setSfWakeUp(sfToken2, 43, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001881 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1882 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1883 mFrameTimeline->setSfPresent(56, presentFence2);
1884 auto displayFrame2 = getDisplayFrame(1);
1885 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1886
1887 // Fences for the first frame have flushed, so the present timestamps should be updated
1888 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
1889 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1890 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1891 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1892
1893 actuals1 = presentedSurfaceFrame1.getActuals();
1894 EXPECT_EQ(actuals1.presentTime, 40);
1895 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1896 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1897 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1898
1899 // Fences for the second frame haven't been flushed yet, so it should be 0
1900 presentFence2->signalForTest(60);
1901 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1902 auto actuals2 = presentedSurfaceFrame2.getActuals();
1903 EXPECT_EQ(actuals2.presentTime, 0);
1904
1905 addEmptyDisplayFrame();
1906
1907 // Fences for the second frame have flushed, so the present timestamps should be updated
1908 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
1909 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1910 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1911 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1912
1913 actuals2 = presentedSurfaceFrame2.getActuals();
1914 EXPECT_EQ(actuals2.presentTime, 60);
1915 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1916 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001917 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
1918 JankType::SurfaceFlingerCpuDeadlineMissed | JankType::AppDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001919}
1920
1921TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001922 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001923 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001924 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1925 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
1926 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
1927
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001928 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
1929 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001930 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001931 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001932 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001933 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001934 surfaceFrame1->setAcquireFenceTime(50);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001935 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001936 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1937 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1938 mFrameTimeline->setSfPresent(56, presentFence1);
1939 auto displayFrame1 = getDisplayFrame(0);
1940 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1941 presentFence1->signalForTest(60);
1942
1943 // Fences for the first frame haven't been flushed yet, so it should be 0
1944 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1945 auto actuals1 = presentedSurfaceFrame1.getActuals();
1946 EXPECT_EQ(actuals1.presentTime, 0);
1947
1948 // Trigger a flush by finalizing the next DisplayFrame
1949 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1950 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001951 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001952 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00001953 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001954 surfaceFrame2->setAcquireFenceTime(84);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001955 mFrameTimeline->setSfWakeUp(sfToken2, 112, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001956 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
1957 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1958 mFrameTimeline->setSfPresent(116, presentFence2);
1959 auto displayFrame2 = getDisplayFrame(1);
1960 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1961 presentFence2->signalForTest(120);
1962
1963 // Fences for the first frame have flushed, so the present timestamps should be updated
1964 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
1965 actuals1 = presentedSurfaceFrame1.getActuals();
1966 EXPECT_EQ(actuals1.endTime, 50);
1967 EXPECT_EQ(actuals1.presentTime, 60);
1968
1969 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1970 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1971 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1972
1973 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1974 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1975 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1976
1977 // Fences for the second frame haven't been flushed yet, so it should be 0
1978 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1979 auto actuals2 = presentedSurfaceFrame2.getActuals();
1980 EXPECT_EQ(actuals2.presentTime, 0);
1981
1982 addEmptyDisplayFrame();
1983
1984 // Fences for the second frame have flushed, so the present timestamps should be updated
1985 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1986 actuals2 = presentedSurfaceFrame2.getActuals();
1987 EXPECT_EQ(actuals2.presentTime, 120);
1988
1989 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1990 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1991 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
1992
1993 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1994 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1995 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
1996 JankType::AppDeadlineMissed | JankType::BufferStuffing);
1997}
Alec Mouriadebf5c2021-01-05 12:57:36 -08001998
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001999TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
2000 // Layer specific increment
2001 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
2002 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2003 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2004 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2005
2006 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2007 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
2008 auto surfaceFrame1 =
2009 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
2010 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002011 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002012 surfaceFrame1->setAcquireFenceTime(50);
2013 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
2014 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2015 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2016 mFrameTimeline->setSfPresent(56, presentFence1);
2017 auto displayFrame1 = getDisplayFrame(0);
2018 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2019 presentFence1->signalForTest(60);
2020
2021 // Fences for the first frame haven't been flushed yet, so it should be 0
2022 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2023 auto actuals1 = presentedSurfaceFrame1.getActuals();
2024 EXPECT_EQ(actuals1.presentTime, 0);
2025
2026 // Trigger a flush by finalizing the next DisplayFrame
2027 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2028 auto surfaceFrame2 =
2029 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
2030 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002031 sLayerNameOne, /*isBuffer*/ true, sGameMode);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002032 surfaceFrame2->setAcquireFenceTime(80);
2033 mFrameTimeline->setSfWakeUp(sfToken2, 82, Fps::fromPeriodNsecs(30));
2034 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
2035 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2036 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2037 mFrameTimeline->setSfPresent(86, presentFence2);
2038 auto displayFrame2 = getDisplayFrame(1);
2039 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2040 presentFence2->signalForTest(90);
2041
2042 // Fences for the first frame have flushed, so the present timestamps should be updated
2043 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2044 actuals1 = presentedSurfaceFrame1.getActuals();
2045 EXPECT_EQ(actuals1.endTime, 50);
2046 EXPECT_EQ(actuals1.presentTime, 60);
2047
2048 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2049 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2050 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2051
2052 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2053 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2054 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2055
2056 // Fences for the second frame haven't been flushed yet, so it should be 0
2057 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2058 auto actuals2 = presentedSurfaceFrame2.getActuals();
2059 EXPECT_EQ(actuals2.presentTime, 0);
2060
2061 addEmptyDisplayFrame();
2062
2063 // Fences for the second frame have flushed, so the present timestamps should be updated
2064 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2065 actuals2 = presentedSurfaceFrame2.getActuals();
2066 EXPECT_EQ(actuals2.presentTime, 90);
2067
2068 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2069 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2070 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
2071
2072 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2073 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2074 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
2075}
2076
Alec Mouriadebf5c2021-01-05 12:57:36 -08002077TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
2078 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
2079}
2080
2081TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002082 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002083
2084 auto surfaceFrame1 =
2085 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002086 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002087 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002088 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2089 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2090 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2091 presentFence1->signalForTest(oneHundredMs);
2092 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2093
2094 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2095}
2096
2097TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002098 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2099 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002100 auto surfaceFrame1 =
2101 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002102 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002103 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002104 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2105 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2106 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2107 presentFence1->signalForTest(oneHundredMs);
2108 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2109
2110 auto surfaceFrame2 =
2111 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002112 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002113 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002114 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2115 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2116 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2117 presentFence2->signalForTest(twoHundredMs);
2118 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2119
2120 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
2121}
2122
2123TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002124 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2125 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002126 auto surfaceFrame1 =
2127 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002128 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002129 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002130 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2131 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2132 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2133 presentFence1->signalForTest(oneHundredMs);
2134 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2135
2136 auto surfaceFrame2 =
2137 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002138 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002139 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002140 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2141 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2142 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2143 presentFence2->signalForTest(twoHundredMs);
2144 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2145
2146 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
2147}
2148
2149TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002150 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2151 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002152 auto surfaceFrame1 =
2153 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002154 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002155 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002156 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2157 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2158 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2159 presentFence1->signalForTest(oneHundredMs);
2160 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2161
2162 auto surfaceFrame2 =
2163 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002164 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002165 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002166 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2167 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2168 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2169 presentFence2->signalForTest(twoHundredMs);
2170 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2171
2172 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2173}
2174
2175TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002176 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2177 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2178 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2179 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2180 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002181 auto surfaceFrame1 =
2182 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002183 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002184 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002185 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2186 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2187 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2188 presentFence1->signalForTest(oneHundredMs);
2189 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2190
2191 auto surfaceFrame2 =
2192 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002193 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002194 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002195 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2196 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2197 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2198 presentFence2->signalForTest(twoHundredMs);
2199 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2200
2201 auto surfaceFrame3 =
2202 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002203 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002204 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002205 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2206 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2207 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2208 presentFence3->signalForTest(threeHundredMs);
2209 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2210
2211 auto surfaceFrame4 =
2212 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002213 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002214 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002215 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2216 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2217 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2218 presentFence4->signalForTest(fiveHundredMs);
2219 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2220
2221 auto surfaceFrame5 =
2222 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002223 sLayerIdOne, sLayerNameOne, sLayerNameOne,
Adithya Srinivasan58069dc2021-06-04 20:37:02 +00002224 /*isBuffer*/ true, sGameMode);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002225 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2226 // Dropped frames will be excluded from fps computation
2227 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2228 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2229 presentFence5->signalForTest(sixHundredMs);
2230 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2231
2232 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2233}
2234
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002235} // namespace android::frametimeline