blob: 6ed614828eaa4d63420b36ed3006b526dbcc5b34 [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 Srinivasanf279e042020-08-17 14:56:27 -070076 maxTokenRetentionTime = mTokenManager->kMaxRetentionTime;
77 }
78
Adithya Srinivasan01189672020-10-20 14:23:05 -070079 // Each tracing session can be used for a single block of Start -> Stop.
80 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
81 perfetto::TraceConfig cfg;
82 cfg.set_duration_ms(500);
83 cfg.add_buffers()->set_size_kb(1024);
84 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
85 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
86
87 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
88 tracingSession->Setup(cfg);
89 return tracingSession;
90 }
91
92 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
93 perfetto::TracingSession* tracingSession) {
94 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
95 perfetto::protos::Trace trace;
96 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
97
98 std::vector<perfetto::protos::TracePacket> packets;
99 for (const auto& packet : trace.packet()) {
100 if (!packet.has_frame_timeline_event()) {
101 continue;
102 }
103 packets.emplace_back(packet);
104 }
105 return packets;
106 }
107
108 void addEmptyDisplayFrame() {
109 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000110 // Trigger a flushPresentFence by calling setSfPresent for the next frame
Adithya Srinivasan01189672020-10-20 14:23:05 -0700111 mFrameTimeline->setSfPresent(2500, presentFence1);
112 }
113
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700114 void flushTokens(nsecs_t flushTime) {
115 std::lock_guard<std::mutex> lock(mTokenManager->mMutex);
116 mTokenManager->flushTokens(flushTime);
117 }
118
119 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
120 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800121 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
122 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700123 }
124
125 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
126 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
127 return mFrameTimeline->mDisplayFrames[idx];
128 }
129
130 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
131 return a.startTime == b.startTime && a.endTime == b.endTime &&
132 a.presentTime == b.presentTime;
133 }
134
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000135 const std::map<int64_t, TokenManagerPrediction>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700136 return mTokenManager->mPredictions;
137 }
138
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000139 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700140 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
141 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
142 }
143
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000144 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
145
146 void flushTrace() {
147 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
148 FrameTimelineDataSource::Trace(
149 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
150 }
151
Alec Mouri9a29e672020-09-14 12:39:14 -0700152 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700153 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
154 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000155 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700156 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700157 uint32_t* maxDisplayFrames;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700158 nsecs_t maxTokenRetentionTime;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000159 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasanead17162021-02-18 02:17:37 +0000160 static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count();
161 static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(2ns).count();
162 static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800163 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
164 kDeadlineThreshold,
165 kStartThreshold};
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700166};
167
Alec Mouri9a29e672020-09-14 12:39:14 -0700168static const std::string sLayerNameOne = "layer1";
169static const std::string sLayerNameTwo = "layer2";
170static constexpr const uid_t sUidOne = 0;
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700171static constexpr pid_t sPidOne = 10;
172static constexpr pid_t sPidTwo = 20;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000173static constexpr int32_t sInputEventId = 5;
Alec Mouriadebf5c2021-01-05 12:57:36 -0800174static constexpr int32_t sLayerIdOne = 1;
175static constexpr int32_t sLayerIdTwo = 2;
Alec Mouri9a29e672020-09-14 12:39:14 -0700176
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700177TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
178 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000179 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700180 flushTokens(systemTime() + maxTokenRetentionTime);
181 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
182 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
183
184 // token1 should have expired
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000185 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700186 EXPECT_EQ(predictions.has_value(), false);
187
188 predictions = mTokenManager->getPredictionsForToken(token2);
189 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
190}
191
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700192TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800193 auto surfaceFrame1 =
194 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000195 sLayerNameOne, sLayerNameOne,
196 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -0800197 auto surfaceFrame2 =
198 mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000199 sLayerNameOne, sLayerNameOne,
200 /*isBuffer*/ true);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700201 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
202 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
203}
204
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700205TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800206 auto surfaceFrame =
207 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000208 sLayerNameOne, sLayerNameOne,
209 /*isBuffer*/ true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700210 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
211}
212
213TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
214 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
215 flushTokens(systemTime() + maxTokenRetentionTime);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000216 auto surfaceFrame =
217 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000218 sLayerIdOne, sLayerNameOne, sLayerNameOne,
219 /*isBuffer*/ true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700220
221 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
222}
223
224TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
225 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000226 auto surfaceFrame =
227 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000228 sLayerIdOne, sLayerNameOne, sLayerNameOne,
229 /*isBuffer*/ true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700230
231 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
232 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
233}
234
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000235TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
236 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
237 constexpr int32_t inputEventId = 1;
238 auto surfaceFrame =
239 mFrameTimeline->createSurfaceFrameForToken({token1, inputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000240 sLayerIdOne, sLayerNameOne, sLayerNameOne,
241 /*isBuffer*/ true);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000242
243 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
244}
245
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700246TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
247 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700248 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000249 auto surfaceFrame1 =
250 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000251 sLayerIdOne, sLayerNameOne, sLayerNameOne,
252 /*isBuffer*/ true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700253
254 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800255 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000256 surfaceFrame1->setDropTime(12);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800257 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
258 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700259 mFrameTimeline->setSfPresent(25, presentFence1);
260 presentFence1->signalForTest(30);
261
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000262 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700263
264 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
265 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000266 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
267 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700268 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
269}
270
271TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800272 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800273 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700274 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
275 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700276 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri9a29e672020-09-14 12:39:14 -0700277 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000278 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800279 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000280 sLayerNameOne, /*isBuffer*/ true);
Alec Mouri9a29e672020-09-14 12:39:14 -0700281 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000282 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800283 sUidOne, sLayerIdTwo, sLayerNameTwo,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000284 sLayerNameTwo, /*isBuffer*/ true);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800285 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800286 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
287 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
288 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
289 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700290 mFrameTimeline->setSfPresent(26, presentFence1);
291 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800292 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
293 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700294 presentFence1->signalForTest(42);
295
296 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800297 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700298 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
299 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
300
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000301 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700302
303 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800304 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700305 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
306 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100307 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
308 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700309}
310
311TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
312 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
313 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800314 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800315 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800316 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700317 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700318 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
319 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
320 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
321 int64_t sfToken = mTokenManager->generateTokenForPredictions(
322 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700323 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000324 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId},
Alec Mouriadebf5c2021-01-05 12:57:36 -0800325 sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000326 sLayerNameOne, sLayerNameOne,
327 /*isBuffer*/ true);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800328 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800329 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
330 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700331 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
332 presentFence->signalForTest(32 + frameTimeFactor);
333 frameTimeFactor += 30;
334 }
335 auto displayFrame0 = getDisplayFrame(0);
336
337 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800338 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700339
340 // Add one more display frame
341 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
342 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
343 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
344 int64_t sfToken = mTokenManager->generateTokenForPredictions(
345 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700346 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000347 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800348 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000349 sLayerNameOne, /*isBuffer*/ true);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800350 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800351 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
352 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700353 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
354 presentFence->signalForTest(32 + frameTimeFactor);
355 displayFrame0 = getDisplayFrame(0);
356
357 // The window should have slided by 1 now and the previous 0th display frame
358 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800359 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700360}
361
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700362TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000363 auto surfaceFrame =
364 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
365 "acquireFenceAfterQueue",
366 "acquireFenceAfterQueue", /*isBuffer*/ true);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700367 surfaceFrame->setActualQueueTime(123);
368 surfaceFrame->setAcquireFenceTime(456);
369 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
370}
371
372TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000373 auto surfaceFrame =
374 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
375 "acquireFenceAfterQueue",
376 "acquireFenceAfterQueue", /*isBuffer*/ true);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700377 surfaceFrame->setActualQueueTime(456);
378 surfaceFrame->setAcquireFenceTime(123);
379 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
380}
381
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700382TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
383 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
384 presentFence->signalForTest(2);
385
386 // Size shouldn't exceed maxDisplayFrames - 64
387 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700388 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800389 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000390 sLayerNameOne, sLayerNameOne,
391 /*isBuffer*/ true);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700392 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800393 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800394 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
395 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700396 mFrameTimeline->setSfPresent(27, presentFence);
397 }
398 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
399
400 // Increase the size to 256
401 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000402 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700403
404 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700405 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800406 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000407 sLayerNameOne, sLayerNameOne,
408 /*isBuffer*/ true);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700409 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800410 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800411 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
412 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700413 mFrameTimeline->setSfPresent(27, presentFence);
414 }
415 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
416
417 // Shrink the size to 128
418 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000419 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700420
421 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700422 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800423 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000424 sLayerNameOne, sLayerNameOne,
425 /*isBuffer*/ true);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700426 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800427 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800428 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
429 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700430 mFrameTimeline->setSfPresent(27, presentFence);
431 }
432 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
433}
Alec Mouri9a29e672020-09-14 12:39:14 -0700434
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000435TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
436 Fps refreshRate = Fps::fromPeriodNsecs(11);
437
438 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
439 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
440 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
441
442 auto surfaceFrame1 =
443 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
444 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000445 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000446 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
447 surfaceFrame1->setAcquireFenceTime(20);
448 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
449 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
450
451 mFrameTimeline->setSfPresent(59, presentFence1);
452 presentFence1->signalForTest(-1);
453 addEmptyDisplayFrame();
454
455 auto displayFrame0 = getDisplayFrame(0);
456 EXPECT_EQ(displayFrame0->getActuals().presentTime, -1);
457 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown);
458 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
459 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
460}
461
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800462// Tests related to TimeStats
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000463TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
464 Fps refreshRate = Fps::fromPeriodNsecs(11);
465 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
466 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
467 int64_t surfaceFrameToken1 = -1;
468 int64_t sfToken1 = -1;
469
470 auto surfaceFrame1 =
471 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
472 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000473 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000474 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
475 surfaceFrame1->setAcquireFenceTime(20);
476 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
477 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
478 presentFence1->signalForTest(70);
479
480 mFrameTimeline->setSfPresent(59, presentFence1);
481}
482
Alec Mouri9a29e672020-09-14 12:39:14 -0700483TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000484 Fps refreshRate = Fps::fromPeriodNsecs(11);
Alec Mouri9a29e672020-09-14 12:39:14 -0700485 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800486 incrementJankyFrames(
487 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
488 sLayerNameOne,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000489 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800490 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700491 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000492 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
493 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
494
Alec Mouri9a29e672020-09-14 12:39:14 -0700495 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000496 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800497 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000498 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000499 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
500 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800501 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
502 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000503 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700504
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000505 mFrameTimeline->setSfPresent(62, presentFence1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700506}
507
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000508TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfGpu) {
509 Fps refreshRate = Fps::fromPeriodNsecs(11);
510 EXPECT_CALL(*mTimeStats,
511 incrementJankyFrames(
512 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
513 sLayerNameOne,
514 JankType::SurfaceFlingerGpuDeadlineMissed, 4, 10,
515 0}));
516 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
517 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
518 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
519 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
520
521 auto surfaceFrame1 =
522 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
523 sUidOne, sLayerIdOne, sLayerNameOne,
524 sLayerNameOne, /*isBuffer*/ true);
525 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
526 surfaceFrame1->setAcquireFenceTime(20);
527 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
528 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
529 gpuFence1->signalForTest(64);
530 presentFence1->signalForTest(70);
531
532 mFrameTimeline->setSfPresent(59, presentFence1, gpuFence1);
533}
534
Alec Mouri9a29e672020-09-14 12:39:14 -0700535TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800536 Fps refreshRate = Fps::fromPeriodNsecs(30);
Alec Mouri9a29e672020-09-14 12:39:14 -0700537 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800538 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
539 sLayerNameOne, JankType::DisplayHAL,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000540 -4, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800541
Alec Mouri9a29e672020-09-14 12:39:14 -0700542 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000543 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
544 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
545
Alec Mouri9a29e672020-09-14 12:39:14 -0700546 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000547 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800548 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000549 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000550 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800551 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000552 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800553 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000554 presentFence1->signalForTest(90);
555 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800556 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700557}
558
559TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800560 Fps refreshRate = Fps(11.0);
Alec Mouri9a29e672020-09-14 12:39:14 -0700561 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000562 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
563 sLayerNameOne,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000564 JankType::AppDeadlineMissed, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000565 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700566 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000567 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
568 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
569
Alec Mouri9a29e672020-09-14 12:39:14 -0700570 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000571 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800572 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000573 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000574 surfaceFrame1->setAcquireFenceTime(45);
575 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700576
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800577 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
578 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000579 presentFence1->signalForTest(90);
580 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100581
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800582 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700583}
584
Adithya Srinivasanead17162021-02-18 02:17:37 +0000585TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000586 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000587 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000588 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
589 sLayerNameOne,
590 JankType::SurfaceFlingerScheduling,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000591 -4, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000592 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000593 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
594 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
595
Adithya Srinivasanead17162021-02-18 02:17:37 +0000596 auto surfaceFrame1 =
597 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800598 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000599 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000600 surfaceFrame1->setAcquireFenceTime(50);
601 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000602
603 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
604 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000605 presentFence1->signalForTest(60);
606 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000607
608 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
609}
610
611TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000612 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000613 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000614 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
615 sLayerNameOne,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000616 JankType::PredictionError, -4, 5,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000617 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000618 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000619 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
620 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
621
Adithya Srinivasanead17162021-02-18 02:17:37 +0000622 auto surfaceFrame1 =
623 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800624 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000625 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000626 surfaceFrame1->setAcquireFenceTime(40);
627 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000628
629 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
630 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000631 presentFence1->signalForTest(65);
632 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000633
634 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
635}
636
637TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000638 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000639 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000640 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
641 sLayerNameOne,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000642 JankType::BufferStuffing, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000643 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000644 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000645 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
646 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
647
Adithya Srinivasanead17162021-02-18 02:17:37 +0000648 auto surfaceFrame1 =
649 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800650 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000651 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000652 surfaceFrame1->setAcquireFenceTime(40);
653 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000654
655 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000656 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000657 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000658 presentFence1->signalForTest(90);
659 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000660
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000661 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000662}
663
Alec Mouri363faf02021-01-29 16:34:55 -0800664TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000665 Fps refreshRate = Fps::fromPeriodNsecs(11);
666 Fps renderRate = Fps::fromPeriodNsecs(30);
Alec Mouri363faf02021-01-29 16:34:55 -0800667 EXPECT_CALL(*mTimeStats,
668 incrementJankyFrames(
669 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000670 JankType::AppDeadlineMissed, -4, 0, 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800671 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000672 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
673 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
674
Alec Mouri363faf02021-01-29 16:34:55 -0800675 auto surfaceFrame1 =
676 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800677 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000678 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000679 surfaceFrame1->setAcquireFenceTime(45);
680 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800681
682 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
683 surfaceFrame1->setRenderRate(renderRate);
684 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000685 presentFence1->signalForTest(90);
686 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800687
688 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
689}
690
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000691TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
692 Fps refreshRate = Fps::fromPeriodNsecs(11);
693 Fps renderRate = Fps::fromPeriodNsecs(30);
694
695 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000696 incrementJankyFrames(
697 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
698 JankType::Unknown | JankType::AppDeadlineMissed,
Adithya Srinivasande272452021-04-10 00:21:00 +0000699 0, 0, 25}));
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000700 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
701 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
702 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
703
704 auto surfaceFrame1 =
705 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
706 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000707 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000708 surfaceFrame1->setAcquireFenceTime(45);
709 // Trigger a prediction expiry
710 flushTokens(systemTime() + maxTokenRetentionTime);
711 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
712
713 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
714 surfaceFrame1->setRenderRate(renderRate);
715 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
716 presentFence1->signalForTest(90);
717 mFrameTimeline->setSfPresent(86, presentFence1);
718
719 auto displayFrame = getDisplayFrame(0);
720 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
721 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
722 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
723 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
724
725 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000726 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000727}
728
Adithya Srinivasan01189672020-10-20 14:23:05 -0700729/*
730 * Tracing Tests
731 *
732 * Trace packets are flushed all the way only when the next packet is traced.
733 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
734 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
735 * will have additional empty frames created for this reason.
736 */
737TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
738 auto tracingSession = getTracingSessionForTest();
739 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700740 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000741 auto surfaceFrame1 =
742 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000743 sLayerIdOne, sLayerNameOne, sLayerNameOne,
744 /*isBuffer*/ true);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700745
746 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800747 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800748 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
749 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700750 mFrameTimeline->setSfPresent(25, presentFence1);
751 presentFence1->signalForTest(30);
752
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000753 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700754
755 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000756 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700757}
758
759TEST_F(FrameTimelineTest, tracing_sanityTest) {
760 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800761 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800762 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700763 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700764
765 tracingSession->StartBlocking();
766 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
767 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000768 auto surfaceFrame1 =
769 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000770 sLayerIdOne, sLayerNameOne, sLayerNameOne,
771 /*isBuffer*/ true);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700772
773 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800774 mFrameTimeline->setSfWakeUp(token2, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800775 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
776 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700777 mFrameTimeline->setSfPresent(25, presentFence1);
778 presentFence1->signalForTest(30);
779
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000780 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000781 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700782 tracingSession->StopBlocking();
783
784 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000785 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000786 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700787}
788
789TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
790 auto tracingSession = getTracingSessionForTest();
791 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700792
793 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700794
795 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800796 mFrameTimeline->setSfWakeUp(-1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700797 mFrameTimeline->setSfPresent(25, presentFence1);
798 presentFence1->signalForTest(30);
799
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000800 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000801 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700802 tracingSession->StopBlocking();
803
804 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000805 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700806}
807
808TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
809 auto tracingSession = getTracingSessionForTest();
810 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700811
812 tracingSession->StartBlocking();
813 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -0800814 auto surfaceFrame1 =
815 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000816 sLayerNameOne, sLayerNameOne,
817 /*isBuffer*/ true);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700818
819 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800820 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800821 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
822 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700823 mFrameTimeline->setSfPresent(25, presentFence1);
824 presentFence1->signalForTest(30);
825
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000826 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000827 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700828 tracingSession->StopBlocking();
829
830 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000831 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
832 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000833 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700834}
835
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000836ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
837 pid_t pid) {
838 ProtoExpectedDisplayFrameStart proto;
839 proto.set_cookie(cookie);
840 proto.set_token(token);
841 proto.set_pid(pid);
842 return proto;
843}
844
845ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
846 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000847 bool gpuComposition, ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000848 ProtoActualDisplayFrameStart proto;
849 proto.set_cookie(cookie);
850 proto.set_token(token);
851 proto.set_pid(pid);
852 proto.set_present_type(presentType);
853 proto.set_on_time_finish(onTimeFinish);
854 proto.set_gpu_composition(gpuComposition);
855 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000856 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000857 return proto;
858}
859
860ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
861 int64_t displayFrameToken,
862 pid_t pid,
863 std::string layerName) {
864 ProtoExpectedSurfaceFrameStart proto;
865 proto.set_cookie(cookie);
866 proto.set_token(token);
867 proto.set_display_frame_token(displayFrameToken);
868 proto.set_pid(pid);
869 proto.set_layer_name(layerName);
870 return proto;
871}
872
873ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
874 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
875 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000876 ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000877 ProtoActualSurfaceFrameStart proto;
878 proto.set_cookie(cookie);
879 proto.set_token(token);
880 proto.set_display_frame_token(displayFrameToken);
881 proto.set_pid(pid);
882 proto.set_layer_name(layerName);
883 proto.set_present_type(presentType);
884 proto.set_on_time_finish(onTimeFinish);
885 proto.set_gpu_composition(gpuComposition);
886 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000887 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000888 return proto;
889}
890
891ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
892 ProtoFrameEnd proto;
893 proto.set_cookie(cookie);
894 return proto;
895}
896
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000897void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
898 const ProtoExpectedDisplayFrameStart& source) {
899 ASSERT_TRUE(received.has_cookie());
900 EXPECT_EQ(received.cookie(), source.cookie());
901
Adithya Srinivasan01189672020-10-20 14:23:05 -0700902 ASSERT_TRUE(received.has_token());
903 EXPECT_EQ(received.token(), source.token());
904
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000905 ASSERT_TRUE(received.has_pid());
906 EXPECT_EQ(received.pid(), source.pid());
907}
908
909void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
910 const ProtoActualDisplayFrameStart& source) {
911 ASSERT_TRUE(received.has_cookie());
912 EXPECT_EQ(received.cookie(), source.cookie());
913
914 ASSERT_TRUE(received.has_token());
915 EXPECT_EQ(received.token(), source.token());
916
917 ASSERT_TRUE(received.has_pid());
918 EXPECT_EQ(received.pid(), source.pid());
919
Adithya Srinivasan01189672020-10-20 14:23:05 -0700920 ASSERT_TRUE(received.has_present_type());
921 EXPECT_EQ(received.present_type(), source.present_type());
922 ASSERT_TRUE(received.has_on_time_finish());
923 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
924 ASSERT_TRUE(received.has_gpu_composition());
925 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
926 ASSERT_TRUE(received.has_jank_type());
927 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000928 ASSERT_TRUE(received.has_prediction_type());
929 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700930}
931
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000932void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
933 const ProtoExpectedSurfaceFrameStart& source) {
934 ASSERT_TRUE(received.has_cookie());
935 EXPECT_EQ(received.cookie(), source.cookie());
936
Adithya Srinivasan01189672020-10-20 14:23:05 -0700937 ASSERT_TRUE(received.has_token());
938 EXPECT_EQ(received.token(), source.token());
939
940 ASSERT_TRUE(received.has_display_frame_token());
941 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
942
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000943 ASSERT_TRUE(received.has_pid());
944 EXPECT_EQ(received.pid(), source.pid());
945
946 ASSERT_TRUE(received.has_layer_name());
947 EXPECT_EQ(received.layer_name(), source.layer_name());
948}
949
950void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
951 const ProtoActualSurfaceFrameStart& source) {
952 ASSERT_TRUE(received.has_cookie());
953 EXPECT_EQ(received.cookie(), source.cookie());
954
955 ASSERT_TRUE(received.has_token());
956 EXPECT_EQ(received.token(), source.token());
957
958 ASSERT_TRUE(received.has_display_frame_token());
959 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
960
961 ASSERT_TRUE(received.has_pid());
962 EXPECT_EQ(received.pid(), source.pid());
963
964 ASSERT_TRUE(received.has_layer_name());
965 EXPECT_EQ(received.layer_name(), source.layer_name());
966
Adithya Srinivasan01189672020-10-20 14:23:05 -0700967 ASSERT_TRUE(received.has_present_type());
968 EXPECT_EQ(received.present_type(), source.present_type());
969 ASSERT_TRUE(received.has_on_time_finish());
970 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
971 ASSERT_TRUE(received.has_gpu_composition());
972 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
973 ASSERT_TRUE(received.has_jank_type());
974 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000975 ASSERT_TRUE(received.has_prediction_type());
976 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000977}
Adithya Srinivasan01189672020-10-20 14:23:05 -0700978
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000979void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
980 ASSERT_TRUE(received.has_cookie());
981 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700982}
983
984TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
985 auto tracingSession = getTracingSessionForTest();
986 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700987
988 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000989 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -0700990
991 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800992 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700993 mFrameTimeline->setSfPresent(26, presentFence1);
994 presentFence1->signalForTest(31);
995
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000996 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000997 auto protoExpectedDisplayFrameStart =
998 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
999 kSurfaceFlingerPid);
1000 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1001 auto protoActualDisplayFrameStart =
1002 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
1003 kSurfaceFlingerPid,
1004 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001005 FrameTimelineEvent::JANK_NONE,
1006 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001007 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001008
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001009 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001010 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001011 tracingSession->StopBlocking();
1012
1013 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001014 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001015
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001016 // Packet - 0 : ExpectedDisplayFrameStart
1017 const auto& packet0 = packets[0];
1018 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001019 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001020 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001021
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001022 const auto& event0 = packet0.frame_timeline_event();
1023 ASSERT_TRUE(event0.has_expected_display_frame_start());
1024 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
1025 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
1026
1027 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
1028 const auto& packet1 = packets[1];
1029 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001030 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001031 ASSERT_TRUE(packet1.has_frame_timeline_event());
1032
1033 const auto& event1 = packet1.frame_timeline_event();
1034 ASSERT_TRUE(event1.has_frame_end());
1035 const auto& expectedDisplayFrameEnd = event1.frame_end();
1036 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
1037
1038 // Packet - 2 : ActualDisplayFrameStart
1039 const auto& packet2 = packets[2];
1040 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001041 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001042 ASSERT_TRUE(packet2.has_frame_timeline_event());
1043
1044 const auto& event2 = packet2.frame_timeline_event();
1045 ASSERT_TRUE(event2.has_actual_display_frame_start());
1046 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1047 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1048
1049 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1050 const auto& packet3 = packets[3];
1051 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001052 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001053 ASSERT_TRUE(packet3.has_frame_timeline_event());
1054
1055 const auto& event3 = packet3.frame_timeline_event();
1056 ASSERT_TRUE(event3.has_frame_end());
1057 const auto& actualDisplayFrameEnd = event3.frame_end();
1058 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001059}
1060
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001061TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1062 auto tracingSession = getTracingSessionForTest();
1063 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1064
1065 tracingSession->StartBlocking();
1066 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1067 // Flush the token so that it would expire
1068 flushTokens(systemTime() + maxTokenRetentionTime);
1069
1070 // Set up the display frame
1071 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
1072 mFrameTimeline->setSfPresent(26, presentFence1);
1073 presentFence1->signalForTest(31);
1074
1075 int64_t traceCookie = snoopCurrentTraceCookie();
1076
1077 auto protoActualDisplayFrameStart =
1078 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1079 kSurfaceFlingerPid,
1080 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001081 false, FrameTimelineEvent::JANK_UNKNOWN,
1082 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001083 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1084
1085 addEmptyDisplayFrame();
1086 flushTrace();
1087 tracingSession->StopBlocking();
1088
1089 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1090 // Only actual timeline packets should be in the trace
1091 EXPECT_EQ(packets.size(), 2u);
1092
1093 // Packet - 0 : ActualDisplayFrameStart
1094 const auto& packet0 = packets[0];
1095 ASSERT_TRUE(packet0.has_timestamp());
1096 EXPECT_EQ(packet0.timestamp(), 20u);
1097 ASSERT_TRUE(packet0.has_frame_timeline_event());
1098
1099 const auto& event0 = packet0.frame_timeline_event();
1100 ASSERT_TRUE(event0.has_actual_display_frame_start());
1101 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1102 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1103
1104 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1105 const auto& packet1 = packets[1];
1106 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001107 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001108 ASSERT_TRUE(packet1.has_frame_timeline_event());
1109
1110 const auto& event1 = packet1.frame_timeline_event();
1111 ASSERT_TRUE(event1.has_frame_end());
1112 const auto& actualDisplayFrameEnd = event1.frame_end();
1113 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1114}
1115
Adithya Srinivasan01189672020-10-20 14:23:05 -07001116TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1117 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001118 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001119 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -07001120 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1121 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1122
1123 tracingSession->StartBlocking();
1124 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1125 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001126
1127 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001128 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001129 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001130 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001131 auto surfaceFrame2 =
1132 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001133 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001134 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001135 surfaceFrame1->setActualQueueTime(10);
1136 surfaceFrame1->setDropTime(15);
1137
1138 surfaceFrame2->setActualQueueTime(15);
1139 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001140
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001141 // First 2 cookies will be used by the DisplayFrame
1142 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1143
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001144 auto protoDroppedSurfaceFrameExpectedStart =
1145 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1146 displayFrameToken1, sPidOne, sLayerNameOne);
1147 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1148 auto protoDroppedSurfaceFrameActualStart =
1149 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1150 displayFrameToken1, sPidOne, sLayerNameOne,
1151 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001152 FrameTimelineEvent::JANK_NONE,
1153 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001154 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001155
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001156 auto protoPresentedSurfaceFrameExpectedStart =
1157 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1158 displayFrameToken1, sPidOne, sLayerNameOne);
1159 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1160 auto protoPresentedSurfaceFrameActualStart =
1161 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1162 displayFrameToken1, sPidOne, sLayerNameOne,
1163 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001164 FrameTimelineEvent::JANK_NONE,
1165 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001166 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001167
1168 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -08001169 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001170 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1171 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001172 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001173 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001174 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001175 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001176
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001177 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001178 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001179 tracingSession->StopBlocking();
1180
1181 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001182 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1183 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001184
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001185 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001186 const auto& packet4 = packets[4];
1187 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001188 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001189 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001190
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001191 const auto& event4 = packet4.frame_timeline_event();
1192 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001193 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1194 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001195
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001196 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001197 const auto& packet5 = packets[5];
1198 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001199 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001200 ASSERT_TRUE(packet5.has_frame_timeline_event());
1201
1202 const auto& event5 = packet5.frame_timeline_event();
1203 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001204 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1205 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001206
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001207 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001208 const auto& packet6 = packets[6];
1209 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001210 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001211 ASSERT_TRUE(packet6.has_frame_timeline_event());
1212
1213 const auto& event6 = packet6.frame_timeline_event();
1214 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001215 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1216 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001217
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001218 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001219 const auto& packet7 = packets[7];
1220 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001221 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001222 ASSERT_TRUE(packet7.has_frame_timeline_event());
1223
1224 const auto& event7 = packet7.frame_timeline_event();
1225 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001226 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1227 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1228
1229 // Packet - 8 : ExpectedSurfaceFrameStart2
1230 const auto& packet8 = packets[8];
1231 ASSERT_TRUE(packet8.has_timestamp());
1232 EXPECT_EQ(packet8.timestamp(), 10u);
1233 ASSERT_TRUE(packet8.has_frame_timeline_event());
1234
1235 const auto& event8 = packet8.frame_timeline_event();
1236 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1237 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1238 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1239
1240 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1241 const auto& packet9 = packets[9];
1242 ASSERT_TRUE(packet9.has_timestamp());
1243 EXPECT_EQ(packet9.timestamp(), 25u);
1244 ASSERT_TRUE(packet9.has_frame_timeline_event());
1245
1246 const auto& event9 = packet9.frame_timeline_event();
1247 ASSERT_TRUE(event9.has_frame_end());
1248 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1249 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1250
1251 // Packet - 10 : ActualSurfaceFrameStart2
1252 const auto& packet10 = packets[10];
1253 ASSERT_TRUE(packet10.has_timestamp());
1254 EXPECT_EQ(packet10.timestamp(), 10u);
1255 ASSERT_TRUE(packet10.has_frame_timeline_event());
1256
1257 const auto& event10 = packet10.frame_timeline_event();
1258 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1259 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1260 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1261
1262 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1263 const auto& packet11 = packets[11];
1264 ASSERT_TRUE(packet11.has_timestamp());
1265 EXPECT_EQ(packet11.timestamp(), 20u);
1266 ASSERT_TRUE(packet11.has_frame_timeline_event());
1267
1268 const auto& event11 = packet11.frame_timeline_event();
1269 ASSERT_TRUE(event11.has_frame_end());
1270 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1271 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1272}
1273
1274TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1275 auto tracingSession = getTracingSessionForTest();
1276 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1277
1278 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001279 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1280 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1281 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001282 int64_t surfaceFrameToken =
1283 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1284
1285 // Flush the token so that it would expire
1286 flushTokens(systemTime() + maxTokenRetentionTime);
1287 auto surfaceFrame1 =
1288 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0},
Alec Mouriadebf5c2021-01-05 12:57:36 -08001289 sPidOne, sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001290 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001291 surfaceFrame1->setActualQueueTime(appEndTime);
1292 surfaceFrame1->setAcquireFenceTime(appEndTime);
1293
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001294 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1295 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1296 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001297 int64_t displayFrameToken =
1298 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1299
1300 // First 2 cookies will be used by the DisplayFrame
1301 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1302
1303 auto protoActualSurfaceFrameStart =
1304 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1305 displayFrameToken, sPidOne, sLayerNameOne,
1306 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001307 false, FrameTimelineEvent::JANK_UNKNOWN,
1308 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001309 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1310
1311 // Set up the display frame
1312 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1313 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1314 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1315 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1316 presentFence1->signalForTest(sfPresentTime);
1317
1318 addEmptyDisplayFrame();
1319 flushTrace();
1320 tracingSession->StopBlocking();
1321
1322 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1323 // Display Frame 4 packets + SurfaceFrame 2 packets
1324 ASSERT_EQ(packets.size(), 6u);
1325
1326 // Packet - 4 : ActualSurfaceFrameStart
1327 const auto& packet4 = packets[4];
1328 ASSERT_TRUE(packet4.has_timestamp());
1329 EXPECT_EQ(packet4.timestamp(),
1330 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1331 ASSERT_TRUE(packet4.has_frame_timeline_event());
1332
1333 const auto& event4 = packet4.frame_timeline_event();
1334 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1335 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1336 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1337
1338 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1339 const auto& packet5 = packets[5];
1340 ASSERT_TRUE(packet5.has_timestamp());
1341 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1342 ASSERT_TRUE(packet5.has_frame_timeline_event());
1343
1344 const auto& event5 = packet5.frame_timeline_event();
1345 ASSERT_TRUE(event5.has_frame_end());
1346 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001347 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001348}
1349
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001350TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDroppedFramesTracedProperly) {
1351 auto tracingSession = getTracingSessionForTest();
1352 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1353
1354 tracingSession->StartBlocking();
1355 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1356 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1357 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
1358 int64_t surfaceFrameToken =
1359 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1360
1361 // Flush the token so that it would expire
1362 flushTokens(systemTime() + maxTokenRetentionTime);
1363 auto surfaceFrame1 =
1364 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0},
1365 sPidOne, sUidOne, sLayerIdOne, sLayerNameOne,
1366 sLayerNameOne, /*isBuffer*/ true);
1367
1368 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(22ms).count();
1369 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1370 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
1371 int64_t displayFrameToken =
1372 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1373
1374 // First 2 cookies will be used by the DisplayFrame
1375 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1376
1377 auto protoActualSurfaceFrameStart =
1378 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1379 displayFrameToken, sPidOne, sLayerNameOne,
1380 FrameTimelineEvent::PRESENT_DROPPED, false, false,
1381 FrameTimelineEvent::JANK_NONE,
1382 FrameTimelineEvent::PREDICTION_EXPIRED);
1383 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1384
1385 // Set up the display frame
1386 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1387 surfaceFrame1->setDropTime(sfStartTime);
1388 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1389 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1390 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1391 presentFence1->signalForTest(sfPresentTime);
1392
1393 addEmptyDisplayFrame();
1394 flushTrace();
1395 tracingSession->StopBlocking();
1396
1397 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1398 // Display Frame 4 packets + SurfaceFrame 2 packets
1399 ASSERT_EQ(packets.size(), 6u);
1400
1401 // Packet - 4 : ActualSurfaceFrameStart
1402 const auto& packet4 = packets[4];
1403 ASSERT_TRUE(packet4.has_timestamp());
1404 EXPECT_EQ(packet4.timestamp(),
1405 static_cast<uint64_t>(sfStartTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1406 ASSERT_TRUE(packet4.has_frame_timeline_event());
1407
1408 const auto& event4 = packet4.frame_timeline_event();
1409 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1410 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1411 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1412
1413 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1414 const auto& packet5 = packets[5];
1415 ASSERT_TRUE(packet5.has_timestamp());
1416 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(sfStartTime));
1417 ASSERT_TRUE(packet5.has_frame_timeline_event());
1418
1419 const auto& event5 = packet5.frame_timeline_event();
1420 ASSERT_TRUE(event5.has_frame_end());
1421 const auto& actualSurfaceFrameEnd = event5.frame_end();
1422 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
1423}
1424
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001425// Tests for Jank classification
1426TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001427 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001428 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001429 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1430 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001431 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001432 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001433 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001434 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001435 sLayerNameOne, /*isBuffer*/ true);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001436 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001437 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1438 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1439 mFrameTimeline->setSfPresent(26, presentFence1);
1440 auto displayFrame = getDisplayFrame(0);
1441 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1442 presentFence1->signalForTest(29);
1443
1444 // Fences haven't been flushed yet, so it should be 0
1445 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1446 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1447
1448 addEmptyDisplayFrame();
1449 displayFrame = getDisplayFrame(0);
1450
1451 // Fences have flushed, so the present timestamps should be updated
1452 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1453 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1454 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1455 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1456 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
1457}
1458
1459TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001460 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001461 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001462 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1463 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001464 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001465 mFrameTimeline->setSfPresent(26, presentFence1);
1466 auto displayFrame = getDisplayFrame(0);
1467 presentFence1->signalForTest(30);
1468
1469 // Fences for the first frame haven't been flushed yet, so it should be 0
1470 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1471
1472 // Trigger a flush by finalizing the next DisplayFrame
1473 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001474 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001475 mFrameTimeline->setSfPresent(56, presentFence2);
1476 displayFrame = getDisplayFrame(0);
1477
1478 // Fences for the first frame have flushed, so the present timestamps should be updated
1479 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1480 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1481 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1482 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1483
1484 // Fences for the second frame haven't been flushed yet, so it should be 0
1485 auto displayFrame2 = getDisplayFrame(1);
1486 presentFence2->signalForTest(65);
1487 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001488 addEmptyDisplayFrame();
1489 displayFrame2 = getDisplayFrame(1);
1490
1491 // Fences for the second frame have flushed, so the present timestamps should be updated
1492 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1493 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1494 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1495 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1496}
1497
1498TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001499 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001500 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001501 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1502 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001503 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001504 mFrameTimeline->setSfPresent(26, presentFence1);
1505 auto displayFrame = getDisplayFrame(0);
1506 presentFence1->signalForTest(50);
1507
1508 // Fences for the first frame haven't been flushed yet, so it should be 0
1509 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1510
1511 // Trigger a flush by finalizing the next DisplayFrame
1512 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001513 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001514 mFrameTimeline->setSfPresent(56, presentFence2);
1515 displayFrame = getDisplayFrame(0);
1516
1517 // Fences for the first frame have flushed, so the present timestamps should be updated
1518 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1519 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1520 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1521 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1522
1523 // Fences for the second frame haven't been flushed yet, so it should be 0
1524 auto displayFrame2 = getDisplayFrame(1);
1525 presentFence2->signalForTest(75);
1526 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1527
1528 addEmptyDisplayFrame();
1529 displayFrame2 = getDisplayFrame(1);
1530
1531 // Fences for the second frame have flushed, so the present timestamps should be updated
1532 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1533 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1534 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1535 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1536}
1537
1538TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001539 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1540 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001541 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001542
1543 mFrameTimeline->setSfPresent(22, presentFence1);
1544 auto displayFrame = getDisplayFrame(0);
1545 presentFence1->signalForTest(28);
1546
1547 // Fences haven't been flushed yet, so it should be 0
1548 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1549
1550 addEmptyDisplayFrame();
1551 displayFrame = getDisplayFrame(0);
1552
1553 // Fences have flushed, so the present timestamps should be updated
1554 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1555 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1556 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1557 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1558}
1559
1560TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001561 /*
1562 * Case 1 - cpu time > vsync period but combined time > deadline > deadline -> cpudeadlinemissed
1563 * Case 2 - cpu time < vsync period but combined time > deadline -> gpudeadlinemissed
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001564 * Case 3 - previous frame ran longer -> sf_stuffing
1565 * Case 4 - Long cpu under SF stuffing -> cpudeadlinemissed
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001566 */
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001567 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001568 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001569 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1570 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001571 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1572 auto gpuFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001573 auto gpuFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1574 auto gpuFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001575 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001576 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001577 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1578 int64_t sfToken4 = mTokenManager->generateTokenForPredictions({112, 120, 120});
1579
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001580 // case 1 - cpu time = 33 - 12 = 21, vsync period = 11
Alec Mouri7d436ec2021-01-27 20:40:50 -08001581 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001582 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
1583 auto displayFrame0 = getDisplayFrame(0);
1584 gpuFence1->signalForTest(36);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001585 presentFence1->signalForTest(52);
1586
1587 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001588 EXPECT_EQ(displayFrame0->getActuals().presentTime, 0);
1589
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001590 // case 2 - cpu time = 56 - 52 = 4, vsync period = 30
1591 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001592 mFrameTimeline->setSfPresent(56, presentFence2, gpuFence2);
1593 auto displayFrame1 = getDisplayFrame(1);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001594 gpuFence2->signalForTest(76);
1595 presentFence2->signalForTest(90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001596
1597 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1598 // Fences have flushed for first displayFrame, so the present timestamps should be updated
1599 EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
1600 EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1601 EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1602 EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001603
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001604 // case 3 - cpu time = 86 - 82 = 4, vsync period = 30
1605 mFrameTimeline->setSfWakeUp(sfToken3, 106, Fps::fromPeriodNsecs(30));
1606 mFrameTimeline->setSfPresent(112, presentFence3, gpuFence3);
1607 auto displayFrame2 = getDisplayFrame(2);
1608 gpuFence3->signalForTest(116);
1609 presentFence3->signalForTest(120);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001610
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001611 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001612 // Fences have flushed for second displayFrame, so the present timestamps should be updated
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001613 EXPECT_EQ(displayFrame1->getActuals().presentTime, 90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001614 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1615 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1616 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001617
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001618 // case 4 - cpu time = 86 - 82 = 4, vsync period = 30
1619 mFrameTimeline->setSfWakeUp(sfToken4, 120, Fps::fromPeriodNsecs(30));
1620 mFrameTimeline->setSfPresent(140, presentFence4, gpuFence4);
1621 auto displayFrame3 = getDisplayFrame(3);
1622 gpuFence4->signalForTest(156);
1623 presentFence4->signalForTest(180);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001624
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001625 EXPECT_EQ(displayFrame3->getActuals().presentTime, 0);
1626 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1627 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1628 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1629 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1630 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerStuffing);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001631
1632 addEmptyDisplayFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001633
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001634 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1635 EXPECT_EQ(displayFrame3->getActuals().presentTime, 180);
1636 EXPECT_EQ(displayFrame3->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1637 EXPECT_EQ(displayFrame3->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1638 EXPECT_EQ(displayFrame3->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001639}
1640
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001641TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001642 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001643 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001644 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1645 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001646 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1647 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1648 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001649 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001650 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001651 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001652 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001653 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001654 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1655 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001656 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001657 auto displayFrame1 = getDisplayFrame(0);
1658 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1659 presentFence1->signalForTest(30);
1660
1661 // Fences for the first frame haven't been flushed yet, so it should be 0
1662 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1663 auto actuals1 = presentedSurfaceFrame1.getActuals();
1664 EXPECT_EQ(actuals1.presentTime, 0);
1665
1666 // Trigger a flush by finalizing the next DisplayFrame
1667 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1668 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001669 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001670 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001671 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001672 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001673 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001674 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1675 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001676 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001677 auto displayFrame2 = getDisplayFrame(1);
1678 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1679
1680 // Fences for the first frame have flushed, so the present timestamps should be updated
1681 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1682 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1683 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1684 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1685
1686 actuals1 = presentedSurfaceFrame1.getActuals();
1687 EXPECT_EQ(actuals1.presentTime, 30);
1688 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1689 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1690 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1691
1692 // Fences for the second frame haven't been flushed yet, so it should be 0
1693 presentFence2->signalForTest(65);
1694 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1695 auto actuals2 = presentedSurfaceFrame2.getActuals();
1696 EXPECT_EQ(actuals2.presentTime, 0);
1697
Alec Mouri363faf02021-01-29 16:34:55 -08001698 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1699
1700 EXPECT_CALL(*mTimeStats,
1701 incrementJankyFrames(
1702 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
Adithya Srinivasan82eef322021-04-10 00:06:04 +00001703 sLayerNameOne, JankType::PredictionError, -3, 5,
Alec Mouri363faf02021-01-29 16:34:55 -08001704 0}));
1705
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001706 addEmptyDisplayFrame();
1707
1708 // Fences for the second frame have flushed, so the present timestamps should be updated
1709 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1710 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1711 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1712 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1713
1714 actuals2 = presentedSurfaceFrame2.getActuals();
1715 EXPECT_EQ(actuals2.presentTime, 65);
1716 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1717 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1718 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1719}
1720
1721TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001722 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001723 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001724 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1725 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001726 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1727 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1728 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001729 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001730 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001731 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001732 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001733 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001734 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1735 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1736 mFrameTimeline->setSfPresent(26, presentFence1);
1737 auto displayFrame1 = getDisplayFrame(0);
1738 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1739 presentFence1->signalForTest(50);
1740
1741 // Fences for the first frame haven't been flushed yet, so it should be 0
1742 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1743 auto actuals1 = presentedSurfaceFrame1.getActuals();
1744 EXPECT_EQ(actuals1.presentTime, 0);
1745
1746 // Trigger a flush by finalizing the next DisplayFrame
1747 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1748 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001749 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001750 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001751 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001752 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001753 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001754 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1755 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001756 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001757 auto displayFrame2 = getDisplayFrame(1);
1758 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1759
1760 // Fences for the first frame have flushed, so the present timestamps should be updated
1761 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1762 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1763 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1764 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1765
1766 actuals1 = presentedSurfaceFrame1.getActuals();
1767 EXPECT_EQ(actuals1.presentTime, 50);
1768 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1769 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1770 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1771
1772 // Fences for the second frame haven't been flushed yet, so it should be 0
1773 presentFence2->signalForTest(86);
1774 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1775 auto actuals2 = presentedSurfaceFrame2.getActuals();
1776 EXPECT_EQ(actuals2.presentTime, 0);
1777
Alec Mouri363faf02021-01-29 16:34:55 -08001778 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1779
1780 EXPECT_CALL(*mTimeStats,
1781 incrementJankyFrames(
1782 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
Adithya Srinivasan82eef322021-04-10 00:06:04 +00001783 sLayerNameOne, JankType::PredictionError, -3, 5,
Alec Mouri363faf02021-01-29 16:34:55 -08001784 0}));
1785
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001786 addEmptyDisplayFrame();
1787
1788 // Fences for the second frame have flushed, so the present timestamps should be updated
1789 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1790 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1791 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1792 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1793
1794 actuals2 = presentedSurfaceFrame2.getActuals();
1795 EXPECT_EQ(actuals2.presentTime, 86);
1796 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1797 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1798 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1799}
1800
1801TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001802 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08001803
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001804 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001805 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001806 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
1807 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001808 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001809 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001810 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001811 surfaceFrame1->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001812 mFrameTimeline->setSfWakeUp(sfToken1, 42, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001813 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1814 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1815 mFrameTimeline->setSfPresent(46, presentFence1);
1816 auto displayFrame1 = getDisplayFrame(0);
1817 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1818 presentFence1->signalForTest(50);
1819
1820 // Fences for the first frame haven't been flushed yet, so it should be 0
1821 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1822 auto actuals1 = presentedSurfaceFrame1.getActuals();
1823 EXPECT_EQ(actuals1.presentTime, 0);
1824
1825 addEmptyDisplayFrame();
1826
1827 // Fences for the first frame have flushed, so the present timestamps should be updated
1828 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1829 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1830 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1831 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1832
1833 actuals1 = presentedSurfaceFrame1.getActuals();
1834 EXPECT_EQ(actuals1.presentTime, 50);
1835 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1836 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1837 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
1838}
1839
1840TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001841 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as only
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001842 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001843 // jank to the SurfaceFrame along with AppDeadlineMissed.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001844
Alec Mouri363faf02021-01-29 16:34:55 -08001845 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001846 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001847 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
1848 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001849 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1850 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
1851 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001852 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001853 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001854 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001855 surfaceFrame1->setAcquireFenceTime(26);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001856 mFrameTimeline->setSfWakeUp(sfToken1, 32, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001857 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1858 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1859 mFrameTimeline->setSfPresent(36, presentFence1);
1860 auto displayFrame1 = getDisplayFrame(0);
1861 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1862 presentFence1->signalForTest(40);
1863
1864 // Fences for the first frame haven't been flushed yet, so it should be 0
1865 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1866 auto actuals1 = presentedSurfaceFrame1.getActuals();
1867 EXPECT_EQ(actuals1.presentTime, 0);
1868
1869 // Trigger a flush by finalizing the next DisplayFrame
1870 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1871 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001872 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001873 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001874 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001875 surfaceFrame2->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001876 mFrameTimeline->setSfWakeUp(sfToken2, 43, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001877 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1878 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1879 mFrameTimeline->setSfPresent(56, presentFence2);
1880 auto displayFrame2 = getDisplayFrame(1);
1881 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1882
1883 // Fences for the first frame have flushed, so the present timestamps should be updated
1884 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
1885 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1886 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1887 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1888
1889 actuals1 = presentedSurfaceFrame1.getActuals();
1890 EXPECT_EQ(actuals1.presentTime, 40);
1891 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1892 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1893 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1894
1895 // Fences for the second frame haven't been flushed yet, so it should be 0
1896 presentFence2->signalForTest(60);
1897 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1898 auto actuals2 = presentedSurfaceFrame2.getActuals();
1899 EXPECT_EQ(actuals2.presentTime, 0);
1900
1901 addEmptyDisplayFrame();
1902
1903 // Fences for the second frame have flushed, so the present timestamps should be updated
1904 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
1905 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1906 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1907 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1908
1909 actuals2 = presentedSurfaceFrame2.getActuals();
1910 EXPECT_EQ(actuals2.presentTime, 60);
1911 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1912 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001913 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
1914 JankType::SurfaceFlingerCpuDeadlineMissed | JankType::AppDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001915}
1916
1917TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001918 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001919 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001920 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1921 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
1922 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
1923
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001924 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
1925 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001926 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001927 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001928 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001929 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001930 surfaceFrame1->setAcquireFenceTime(50);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001931 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001932 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1933 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1934 mFrameTimeline->setSfPresent(56, presentFence1);
1935 auto displayFrame1 = getDisplayFrame(0);
1936 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1937 presentFence1->signalForTest(60);
1938
1939 // Fences for the first frame haven't been flushed yet, so it should be 0
1940 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1941 auto actuals1 = presentedSurfaceFrame1.getActuals();
1942 EXPECT_EQ(actuals1.presentTime, 0);
1943
1944 // Trigger a flush by finalizing the next DisplayFrame
1945 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1946 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001947 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001948 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001949 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001950 surfaceFrame2->setAcquireFenceTime(84);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001951 mFrameTimeline->setSfWakeUp(sfToken2, 112, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001952 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
1953 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1954 mFrameTimeline->setSfPresent(116, presentFence2);
1955 auto displayFrame2 = getDisplayFrame(1);
1956 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1957 presentFence2->signalForTest(120);
1958
1959 // Fences for the first frame have flushed, so the present timestamps should be updated
1960 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
1961 actuals1 = presentedSurfaceFrame1.getActuals();
1962 EXPECT_EQ(actuals1.endTime, 50);
1963 EXPECT_EQ(actuals1.presentTime, 60);
1964
1965 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1966 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1967 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1968
1969 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1970 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1971 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1972
1973 // Fences for the second frame haven't been flushed yet, so it should be 0
1974 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1975 auto actuals2 = presentedSurfaceFrame2.getActuals();
1976 EXPECT_EQ(actuals2.presentTime, 0);
1977
1978 addEmptyDisplayFrame();
1979
1980 // Fences for the second frame have flushed, so the present timestamps should be updated
1981 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1982 actuals2 = presentedSurfaceFrame2.getActuals();
1983 EXPECT_EQ(actuals2.presentTime, 120);
1984
1985 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1986 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1987 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
1988
1989 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1990 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1991 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
1992 JankType::AppDeadlineMissed | JankType::BufferStuffing);
1993}
Alec Mouriadebf5c2021-01-05 12:57:36 -08001994
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001995TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
1996 // Layer specific increment
1997 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
1998 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1999 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2000 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2001
2002 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2003 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
2004 auto surfaceFrame1 =
2005 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
2006 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002007 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002008 surfaceFrame1->setAcquireFenceTime(50);
2009 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
2010 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2011 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2012 mFrameTimeline->setSfPresent(56, presentFence1);
2013 auto displayFrame1 = getDisplayFrame(0);
2014 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2015 presentFence1->signalForTest(60);
2016
2017 // Fences for the first frame haven't been flushed yet, so it should be 0
2018 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2019 auto actuals1 = presentedSurfaceFrame1.getActuals();
2020 EXPECT_EQ(actuals1.presentTime, 0);
2021
2022 // Trigger a flush by finalizing the next DisplayFrame
2023 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2024 auto surfaceFrame2 =
2025 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
2026 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002027 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002028 surfaceFrame2->setAcquireFenceTime(80);
2029 mFrameTimeline->setSfWakeUp(sfToken2, 82, Fps::fromPeriodNsecs(30));
2030 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
2031 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2032 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2033 mFrameTimeline->setSfPresent(86, presentFence2);
2034 auto displayFrame2 = getDisplayFrame(1);
2035 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2036 presentFence2->signalForTest(90);
2037
2038 // Fences for the first frame have flushed, so the present timestamps should be updated
2039 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2040 actuals1 = presentedSurfaceFrame1.getActuals();
2041 EXPECT_EQ(actuals1.endTime, 50);
2042 EXPECT_EQ(actuals1.presentTime, 60);
2043
2044 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2045 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2046 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2047
2048 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2049 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2050 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2051
2052 // Fences for the second frame haven't been flushed yet, so it should be 0
2053 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2054 auto actuals2 = presentedSurfaceFrame2.getActuals();
2055 EXPECT_EQ(actuals2.presentTime, 0);
2056
2057 addEmptyDisplayFrame();
2058
2059 // Fences for the second frame have flushed, so the present timestamps should be updated
2060 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2061 actuals2 = presentedSurfaceFrame2.getActuals();
2062 EXPECT_EQ(actuals2.presentTime, 90);
2063
2064 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2065 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2066 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
2067
2068 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2069 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2070 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
2071}
2072
Alec Mouriadebf5c2021-01-05 12:57:36 -08002073TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
2074 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
2075}
2076
2077TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002078 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002079
2080 auto surfaceFrame1 =
2081 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002082 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2083 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002084 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2085 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2086 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2087 presentFence1->signalForTest(oneHundredMs);
2088 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2089
2090 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2091}
2092
2093TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002094 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2095 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002096 auto surfaceFrame1 =
2097 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002098 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2099 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002100 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2101 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2102 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2103 presentFence1->signalForTest(oneHundredMs);
2104 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2105
2106 auto surfaceFrame2 =
2107 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002108 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2109 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002110 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2111 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2112 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2113 presentFence2->signalForTest(twoHundredMs);
2114 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2115
2116 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
2117}
2118
2119TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002120 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2121 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002122 auto surfaceFrame1 =
2123 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002124 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2125 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002126 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2127 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2128 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2129 presentFence1->signalForTest(oneHundredMs);
2130 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2131
2132 auto surfaceFrame2 =
2133 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002134 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
2135 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002136 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2137 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2138 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2139 presentFence2->signalForTest(twoHundredMs);
2140 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2141
2142 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
2143}
2144
2145TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002146 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2147 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002148 auto surfaceFrame1 =
2149 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002150 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2151 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002152 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2153 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2154 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2155 presentFence1->signalForTest(oneHundredMs);
2156 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2157
2158 auto surfaceFrame2 =
2159 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002160 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
2161 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002162 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2163 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2164 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2165 presentFence2->signalForTest(twoHundredMs);
2166 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2167
2168 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2169}
2170
2171TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002172 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2173 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2174 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2175 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2176 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002177 auto surfaceFrame1 =
2178 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002179 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2180 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002181 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2182 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2183 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2184 presentFence1->signalForTest(oneHundredMs);
2185 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2186
2187 auto surfaceFrame2 =
2188 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002189 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2190 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002191 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2192 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2193 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2194 presentFence2->signalForTest(twoHundredMs);
2195 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2196
2197 auto surfaceFrame3 =
2198 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002199 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
2200 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002201 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2202 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2203 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2204 presentFence3->signalForTest(threeHundredMs);
2205 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2206
2207 auto surfaceFrame4 =
2208 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002209 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2210 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002211 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2212 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2213 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2214 presentFence4->signalForTest(fiveHundredMs);
2215 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2216
2217 auto surfaceFrame5 =
2218 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002219 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2220 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002221 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2222 // Dropped frames will be excluded from fps computation
2223 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2224 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2225 presentFence5->signalForTest(sixHundredMs);
2226 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2227
2228 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2229}
2230
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002231} // namespace android::frametimeline