blob: c6a41159c14c88bb97be3a762cdda4cd2764ae3d [file] [log] [blame]
Adithya Srinivasanf279e042020-08-17 14:56:27 -07001/*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Marin Shalamanovbed7fd32020-12-21 20:02:20 +010017
Alec Mouri9a29e672020-09-14 12:39:14 -070018#include "gmock/gmock-spec-builders.h"
19#include "mock/MockTimeStats.h"
Adithya Srinivasanf279e042020-08-17 14:56:27 -070020#undef LOG_TAG
21#define LOG_TAG "LibSurfaceFlingerUnittests"
22
23#include <FrameTimeline/FrameTimeline.h>
24#include <gtest/gtest.h>
25#include <log/log.h>
Adithya Srinivasan01189672020-10-20 14:23:05 -070026#include <perfetto/trace/trace.pb.h>
Adithya Srinivasanf279e042020-08-17 14:56:27 -070027#include <cinttypes>
28
29using namespace std::chrono_literals;
Alec Mouri363faf02021-01-29 16:34:55 -080030using testing::_;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -080031using testing::AtLeast;
Alec Mouri9a29e672020-09-14 12:39:14 -070032using testing::Contains;
Adithya Srinivasan01189672020-10-20 14:23:05 -070033using FrameTimelineEvent = perfetto::protos::FrameTimelineEvent;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000034using ProtoExpectedDisplayFrameStart =
35 perfetto::protos::FrameTimelineEvent_ExpectedDisplayFrameStart;
36using ProtoExpectedSurfaceFrameStart =
37 perfetto::protos::FrameTimelineEvent_ExpectedSurfaceFrameStart;
38using ProtoActualDisplayFrameStart = perfetto::protos::FrameTimelineEvent_ActualDisplayFrameStart;
39using ProtoActualSurfaceFrameStart = perfetto::protos::FrameTimelineEvent_ActualSurfaceFrameStart;
40using ProtoFrameEnd = perfetto::protos::FrameTimelineEvent_FrameEnd;
Adithya Srinivasan01189672020-10-20 14:23:05 -070041using ProtoPresentType = perfetto::protos::FrameTimelineEvent_PresentType;
42using ProtoJankType = perfetto::protos::FrameTimelineEvent_JankType;
Adithya Srinivasan78e58af2021-02-25 00:08:08 +000043using ProtoPredictionType = perfetto::protos::FrameTimelineEvent_PredictionType;
Alec Mouri9a29e672020-09-14 12:39:14 -070044
Adithya Srinivasanf279e042020-08-17 14:56:27 -070045namespace android::frametimeline {
46
47class FrameTimelineTest : public testing::Test {
48public:
49 FrameTimelineTest() {
50 const ::testing::TestInfo* const test_info =
51 ::testing::UnitTest::GetInstance()->current_test_info();
52 ALOGD("**** Setting up for %s.%s\n", test_info->test_case_name(), test_info->name());
53 }
54
55 ~FrameTimelineTest() {
56 const ::testing::TestInfo* const test_info =
57 ::testing::UnitTest::GetInstance()->current_test_info();
58 ALOGD("**** Tearing down after %s.%s\n", test_info->test_case_name(), test_info->name());
59 }
60
Adithya Srinivasan01189672020-10-20 14:23:05 -070061 static void SetUpTestSuite() {
62 // Need to initialize tracing in process for testing, and only once per test suite.
63 perfetto::TracingInitArgs args;
64 args.backends = perfetto::kInProcessBackend;
65 perfetto::Tracing::Initialize(args);
66 }
67
Adithya Srinivasanf279e042020-08-17 14:56:27 -070068 void SetUp() override {
Alec Mouri9a29e672020-09-14 12:39:14 -070069 mTimeStats = std::make_shared<mock::TimeStats>();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000070 mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats, kSurfaceFlingerPid,
Adithya Srinivasan82eef322021-04-10 00:06:04 +000071 kTestThresholds);
Adithya Srinivasan01189672020-10-20 14:23:05 -070072 mFrameTimeline->registerDataSource();
Adithya Srinivasanf279e042020-08-17 14:56:27 -070073 mTokenManager = &mFrameTimeline->mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +000074 mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
Adithya Srinivasan2d736322020-10-01 16:53:48 -070075 maxDisplayFrames = &mFrameTimeline->mMaxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +000076 maxTokens = mTokenManager->kMaxTokens;
Adithya Srinivasanf279e042020-08-17 14:56:27 -070077 }
78
Adithya Srinivasan01189672020-10-20 14:23:05 -070079 // Each tracing session can be used for a single block of Start -> Stop.
80 static std::unique_ptr<perfetto::TracingSession> getTracingSessionForTest() {
81 perfetto::TraceConfig cfg;
82 cfg.set_duration_ms(500);
83 cfg.add_buffers()->set_size_kb(1024);
84 auto* ds_cfg = cfg.add_data_sources()->mutable_config();
85 ds_cfg->set_name(impl::FrameTimeline::kFrameTimelineDataSource);
86
87 auto tracingSession = perfetto::Tracing::NewTrace(perfetto::kInProcessBackend);
88 tracingSession->Setup(cfg);
89 return tracingSession;
90 }
91
92 std::vector<perfetto::protos::TracePacket> readFrameTimelinePacketsBlocking(
93 perfetto::TracingSession* tracingSession) {
94 std::vector<char> raw_trace = tracingSession->ReadTraceBlocking();
95 perfetto::protos::Trace trace;
96 EXPECT_TRUE(trace.ParseFromArray(raw_trace.data(), int(raw_trace.size())));
97
98 std::vector<perfetto::protos::TracePacket> packets;
99 for (const auto& packet : trace.packet()) {
100 if (!packet.has_frame_timeline_event()) {
101 continue;
102 }
103 packets.emplace_back(packet);
104 }
105 return packets;
106 }
107
108 void addEmptyDisplayFrame() {
109 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000110 // Trigger a flushPresentFence by calling setSfPresent for the next frame
Adithya Srinivasan01189672020-10-20 14:23:05 -0700111 mFrameTimeline->setSfPresent(2500, presentFence1);
112 }
113
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000114 void flushTokens() {
115 for (size_t i = 0; i < maxTokens; i++) {
116 mTokenManager->generateTokenForPredictions({});
117 }
118 EXPECT_EQ(getPredictions().size(), maxTokens);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700119 }
120
121 SurfaceFrame& getSurfaceFrame(size_t displayFrameIdx, size_t surfaceFrameIdx) {
122 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800123 return *(mFrameTimeline->mDisplayFrames[displayFrameIdx]
124 ->getSurfaceFrames()[surfaceFrameIdx]);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700125 }
126
127 std::shared_ptr<impl::FrameTimeline::DisplayFrame> getDisplayFrame(size_t idx) {
128 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
129 return mFrameTimeline->mDisplayFrames[idx];
130 }
131
132 static bool compareTimelineItems(const TimelineItem& a, const TimelineItem& b) {
133 return a.startTime == b.startTime && a.endTime == b.endTime &&
134 a.presentTime == b.presentTime;
135 }
136
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000137 const std::map<int64_t, TimelineItem>& getPredictions() const {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700138 return mTokenManager->mPredictions;
139 }
140
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000141 uint32_t getNumberOfDisplayFrames() const {
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700142 std::lock_guard<std::mutex> lock(mFrameTimeline->mMutex);
143 return static_cast<uint32_t>(mFrameTimeline->mDisplayFrames.size());
144 }
145
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000146 int64_t snoopCurrentTraceCookie() const { return mTraceCookieCounter->mTraceCookie; }
147
148 void flushTrace() {
149 using FrameTimelineDataSource = impl::FrameTimeline::FrameTimelineDataSource;
150 FrameTimelineDataSource::Trace(
151 [&](FrameTimelineDataSource::TraceContext ctx) { ctx.Flush(); });
152 }
153
Alec Mouri9a29e672020-09-14 12:39:14 -0700154 std::shared_ptr<mock::TimeStats> mTimeStats;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700155 std::unique_ptr<impl::FrameTimeline> mFrameTimeline;
156 impl::TokenManager* mTokenManager;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000157 TraceCookieCounter* mTraceCookieCounter;
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700158 FenceToFenceTimeMap fenceFactory;
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700159 uint32_t* maxDisplayFrames;
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000160 size_t maxTokens;
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000161 static constexpr pid_t kSurfaceFlingerPid = 666;
Adithya Srinivasanead17162021-02-18 02:17:37 +0000162 static constexpr nsecs_t kPresentThreshold = std::chrono::nanoseconds(2ns).count();
163 static constexpr nsecs_t kDeadlineThreshold = std::chrono::nanoseconds(2ns).count();
164 static constexpr nsecs_t kStartThreshold = std::chrono::nanoseconds(2ns).count();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800165 static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
166 kDeadlineThreshold,
167 kStartThreshold};
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700168};
169
Alec Mouri9a29e672020-09-14 12:39:14 -0700170static const std::string sLayerNameOne = "layer1";
171static const std::string sLayerNameTwo = "layer2";
172static constexpr const uid_t sUidOne = 0;
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700173static constexpr pid_t sPidOne = 10;
174static constexpr pid_t sPidTwo = 20;
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000175static constexpr int32_t sInputEventId = 5;
Alec Mouriadebf5c2021-01-05 12:57:36 -0800176static constexpr int32_t sLayerIdOne = 1;
177static constexpr int32_t sLayerIdTwo = 2;
Alec Mouri9a29e672020-09-14 12:39:14 -0700178
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700179TEST_F(FrameTimelineTest, tokenManagerRemovesStalePredictions) {
180 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000181 EXPECT_EQ(getPredictions().size(), 1u);
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000182 flushTokens();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700183 int64_t token2 = mTokenManager->generateTokenForPredictions({10, 20, 30});
184 std::optional<TimelineItem> predictions = mTokenManager->getPredictionsForToken(token1);
185
186 // token1 should have expired
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700187 EXPECT_EQ(predictions.has_value(), false);
188
189 predictions = mTokenManager->getPredictionsForToken(token2);
190 EXPECT_EQ(compareTimelineItems(*predictions, TimelineItem(10, 20, 30)), true);
191}
192
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700193TEST_F(FrameTimelineTest, createSurfaceFrameForToken_getOwnerPidReturnsCorrectPid) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800194 auto surfaceFrame1 =
195 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000196 sLayerNameOne, sLayerNameOne,
197 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -0800198 auto surfaceFrame2 =
199 mFrameTimeline->createSurfaceFrameForToken({}, sPidTwo, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000200 sLayerNameOne, sLayerNameOne,
201 /*isBuffer*/ true);
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700202 EXPECT_EQ(surfaceFrame1->getOwnerPid(), sPidOne);
203 EXPECT_EQ(surfaceFrame2->getOwnerPid(), sPidTwo);
204}
205
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700206TEST_F(FrameTimelineTest, createSurfaceFrameForToken_noToken) {
Alec Mouriadebf5c2021-01-05 12:57:36 -0800207 auto surfaceFrame =
208 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000209 sLayerNameOne, sLayerNameOne,
210 /*isBuffer*/ true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700211 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::None);
212}
213
214TEST_F(FrameTimelineTest, createSurfaceFrameForToken_expiredToken) {
215 int64_t token1 = mTokenManager->generateTokenForPredictions({0, 0, 0});
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000216 flushTokens();
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000217 auto surfaceFrame =
218 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000219 sLayerIdOne, sLayerNameOne, sLayerNameOne,
220 /*isBuffer*/ true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700221
222 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Expired);
223}
224
225TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validToken) {
226 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000227 auto surfaceFrame =
228 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000229 sLayerIdOne, sLayerNameOne, sLayerNameOne,
230 /*isBuffer*/ true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700231
232 EXPECT_EQ(surfaceFrame->getPredictionState(), PredictionState::Valid);
233 EXPECT_EQ(compareTimelineItems(surfaceFrame->getPredictions(), TimelineItem(10, 20, 30)), true);
234}
235
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000236TEST_F(FrameTimelineTest, createSurfaceFrameForToken_validInputEventId) {
237 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
238 constexpr int32_t inputEventId = 1;
239 auto surfaceFrame =
240 mFrameTimeline->createSurfaceFrameForToken({token1, inputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000241 sLayerIdOne, sLayerNameOne, sLayerNameOne,
242 /*isBuffer*/ true);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000243
244 EXPECT_EQ(inputEventId, surfaceFrame->getInputEventId());
245}
246
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700247TEST_F(FrameTimelineTest, presentFenceSignaled_droppedFramesNotUpdated) {
248 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700249 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000250 auto surfaceFrame1 =
251 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000252 sLayerIdOne, sLayerNameOne, sLayerNameOne,
253 /*isBuffer*/ true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700254
255 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800256 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000257 surfaceFrame1->setDropTime(12);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800258 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
259 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700260 mFrameTimeline->setSfPresent(25, presentFence1);
261 presentFence1->signalForTest(30);
262
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000263 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700264
265 auto& droppedSurfaceFrame = getSurfaceFrame(0, 0);
266 EXPECT_EQ(droppedSurfaceFrame.getPresentState(), SurfaceFrame::PresentState::Dropped);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000267 EXPECT_EQ(0u, droppedSurfaceFrame.getActuals().endTime);
268 EXPECT_EQ(12u, droppedSurfaceFrame.getDropTime());
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700269 EXPECT_EQ(droppedSurfaceFrame.getActuals().presentTime, 0);
270}
271
272TEST_F(FrameTimelineTest, presentFenceSignaled_presentedFramesUpdated) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800273 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800274 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700275 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
276 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700277 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri9a29e672020-09-14 12:39:14 -0700278 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000279 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800280 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000281 sLayerNameOne, /*isBuffer*/ true);
Alec Mouri9a29e672020-09-14 12:39:14 -0700282 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000283 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800284 sUidOne, sLayerIdTwo, sLayerNameTwo,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000285 sLayerNameTwo, /*isBuffer*/ true);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800286 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800287 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
288 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
289 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
290 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700291 mFrameTimeline->setSfPresent(26, presentFence1);
292 auto displayFrame = getDisplayFrame(0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800293 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
294 auto& presentedSurfaceFrame2 = getSurfaceFrame(0, 1);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700295 presentFence1->signalForTest(42);
296
297 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800298 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700299 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 0);
300 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 0);
301
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000302 addEmptyDisplayFrame();
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700303
304 // Fences have flushed, so the present timestamps should be updated
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800305 EXPECT_EQ(displayFrame->getActuals().presentTime, 42);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700306 EXPECT_EQ(presentedSurfaceFrame1.getActuals().presentTime, 42);
307 EXPECT_EQ(presentedSurfaceFrame2.getActuals().presentTime, 42);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100308 EXPECT_NE(surfaceFrame1->getJankType(), std::nullopt);
309 EXPECT_NE(surfaceFrame2->getJankType(), std::nullopt);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700310}
311
312TEST_F(FrameTimelineTest, displayFramesSlidingWindowMovesAfterLimit) {
313 // Insert kMaxDisplayFrames' count of DisplayFrames to fill the deque
314 int frameTimeFactor = 0;
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800315 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800316 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_))
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800317 .Times(static_cast<int32_t>(*maxDisplayFrames));
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700318 for (size_t i = 0; i < *maxDisplayFrames; i++) {
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700319 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
320 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
321 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
322 int64_t sfToken = mTokenManager->generateTokenForPredictions(
323 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700324 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000325 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId},
Alec Mouriadebf5c2021-01-05 12:57:36 -0800326 sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000327 sLayerNameOne, sLayerNameOne,
328 /*isBuffer*/ true);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800329 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800330 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
331 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700332 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
333 presentFence->signalForTest(32 + frameTimeFactor);
334 frameTimeFactor += 30;
335 }
336 auto displayFrame0 = getDisplayFrame(0);
337
338 // The 0th Display Frame should have actuals 22, 27, 32
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800339 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(22, 27, 32)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700340
341 // Add one more display frame
342 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
343 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions(
344 {10 + frameTimeFactor, 20 + frameTimeFactor, 30 + frameTimeFactor});
345 int64_t sfToken = mTokenManager->generateTokenForPredictions(
346 {22 + frameTimeFactor, 26 + frameTimeFactor, 30 + frameTimeFactor});
Alec Mouri9a29e672020-09-14 12:39:14 -0700347 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000348 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800349 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000350 sLayerNameOne, /*isBuffer*/ true);
Alec Mouri7d436ec2021-01-27 20:40:50 -0800351 mFrameTimeline->setSfWakeUp(sfToken, 22 + frameTimeFactor, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800352 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
353 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700354 mFrameTimeline->setSfPresent(27 + frameTimeFactor, presentFence);
355 presentFence->signalForTest(32 + frameTimeFactor);
356 displayFrame0 = getDisplayFrame(0);
357
358 // The window should have slided by 1 now and the previous 0th display frame
359 // should have been removed from the deque
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800360 EXPECT_EQ(compareTimelineItems(displayFrame0->getActuals(), TimelineItem(52, 57, 62)), true);
Adithya Srinivasanf279e042020-08-17 14:56:27 -0700361}
362
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700363TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceAfterQueue) {
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000364 auto surfaceFrame =
365 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
366 "acquireFenceAfterQueue",
367 "acquireFenceAfterQueue", /*isBuffer*/ true);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700368 surfaceFrame->setActualQueueTime(123);
369 surfaceFrame->setAcquireFenceTime(456);
370 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
371}
372
373TEST_F(FrameTimelineTest, surfaceFrameEndTimeAcquireFenceBeforeQueue) {
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000374 auto surfaceFrame =
375 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, 0, sLayerIdOne,
376 "acquireFenceAfterQueue",
377 "acquireFenceAfterQueue", /*isBuffer*/ true);
Ady Abraham7f8a1e62020-09-28 16:09:35 -0700378 surfaceFrame->setActualQueueTime(456);
379 surfaceFrame->setAcquireFenceTime(123);
380 EXPECT_EQ(surfaceFrame->getActuals().endTime, 456);
381}
382
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700383TEST_F(FrameTimelineTest, setMaxDisplayFramesSetsSizeProperly) {
384 auto presentFence = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
385 presentFence->signalForTest(2);
386
387 // Size shouldn't exceed maxDisplayFrames - 64
388 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700389 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800390 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000391 sLayerNameOne, sLayerNameOne,
392 /*isBuffer*/ true);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700393 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800394 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800395 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
396 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700397 mFrameTimeline->setSfPresent(27, presentFence);
398 }
399 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
400
401 // Increase the size to 256
402 mFrameTimeline->setMaxDisplayFrames(256);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000403 EXPECT_EQ(*maxDisplayFrames, 256u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700404
405 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700406 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800407 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000408 sLayerNameOne, sLayerNameOne,
409 /*isBuffer*/ true);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700410 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800411 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800412 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
413 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700414 mFrameTimeline->setSfPresent(27, presentFence);
415 }
416 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
417
418 // Shrink the size to 128
419 mFrameTimeline->setMaxDisplayFrames(128);
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000420 EXPECT_EQ(*maxDisplayFrames, 128u);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700421
422 for (size_t i = 0; i < *maxDisplayFrames + 10; i++) {
Adithya Srinivasan9febda82020-10-19 10:49:41 -0700423 auto surfaceFrame =
Alec Mouriadebf5c2021-01-05 12:57:36 -0800424 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000425 sLayerNameOne, sLayerNameOne,
426 /*isBuffer*/ true);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700427 int64_t sfToken = mTokenManager->generateTokenForPredictions({22, 26, 30});
Alec Mouri7d436ec2021-01-27 20:40:50 -0800428 mFrameTimeline->setSfWakeUp(sfToken, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800429 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
430 mFrameTimeline->addSurfaceFrame(surfaceFrame);
Adithya Srinivasan2d736322020-10-01 16:53:48 -0700431 mFrameTimeline->setSfPresent(27, presentFence);
432 }
433 EXPECT_EQ(getNumberOfDisplayFrames(), *maxDisplayFrames);
434}
Alec Mouri9a29e672020-09-14 12:39:14 -0700435
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000436TEST_F(FrameTimelineTest, presentFenceSignaled_invalidSignalTime) {
437 Fps refreshRate = Fps::fromPeriodNsecs(11);
438
439 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
440 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
441 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
442
443 auto surfaceFrame1 =
444 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
445 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000446 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000447 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
448 surfaceFrame1->setAcquireFenceTime(20);
449 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
450 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
451
452 mFrameTimeline->setSfPresent(59, presentFence1);
453 presentFence1->signalForTest(-1);
454 addEmptyDisplayFrame();
455
456 auto displayFrame0 = getDisplayFrame(0);
457 EXPECT_EQ(displayFrame0->getActuals().presentTime, -1);
458 EXPECT_EQ(displayFrame0->getJankType(), JankType::Unknown);
459 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, -1);
460 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown);
461}
462
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800463// Tests related to TimeStats
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000464TEST_F(FrameTimelineTest, presentFenceSignaled_doesNotReportForInvalidTokens) {
465 Fps refreshRate = Fps::fromPeriodNsecs(11);
466 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(0);
467 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
468 int64_t surfaceFrameToken1 = -1;
469 int64_t sfToken1 = -1;
470
471 auto surfaceFrame1 =
472 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
473 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000474 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan7c4ac7a2021-03-08 23:48:03 +0000475 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
476 surfaceFrame1->setAcquireFenceTime(20);
477 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
478 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
479 presentFence1->signalForTest(70);
480
481 mFrameTimeline->setSfPresent(59, presentFence1);
482}
483
Alec Mouri9a29e672020-09-14 12:39:14 -0700484TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000485 Fps refreshRate = Fps::fromPeriodNsecs(11);
Alec Mouri9a29e672020-09-14 12:39:14 -0700486 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800487 incrementJankyFrames(
488 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
489 sLayerNameOne,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000490 JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
Alec Mouri363faf02021-01-29 16:34:55 -0800491 0}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700492 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000493 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
494 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
495
Alec Mouri9a29e672020-09-14 12:39:14 -0700496 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000497 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800498 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000499 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000500 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
501 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800502 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
503 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000504 presentFence1->signalForTest(70);
Alec Mouri9a29e672020-09-14 12:39:14 -0700505
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000506 mFrameTimeline->setSfPresent(62, presentFence1);
Alec Mouri9a29e672020-09-14 12:39:14 -0700507}
508
Adithya Srinivasan36b01af2021-04-07 22:29:47 +0000509TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfGpu) {
510 Fps refreshRate = Fps::fromPeriodNsecs(11);
511 EXPECT_CALL(*mTimeStats,
512 incrementJankyFrames(
513 TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
514 sLayerNameOne,
515 JankType::SurfaceFlingerGpuDeadlineMissed, 4, 10,
516 0}));
517 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
518 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
519 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
520 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
521
522 auto surfaceFrame1 =
523 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
524 sUidOne, sLayerIdOne, sLayerNameOne,
525 sLayerNameOne, /*isBuffer*/ true);
526 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
527 surfaceFrame1->setAcquireFenceTime(20);
528 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
529 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
530 gpuFence1->signalForTest(64);
531 presentFence1->signalForTest(70);
532
533 mFrameTimeline->setSfPresent(59, presentFence1, gpuFence1);
534}
535
Alec Mouri9a29e672020-09-14 12:39:14 -0700536TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800537 Fps refreshRate = Fps::fromPeriodNsecs(30);
Alec Mouri9a29e672020-09-14 12:39:14 -0700538 EXPECT_CALL(*mTimeStats,
Alec Mouri363faf02021-01-29 16:34:55 -0800539 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
540 sLayerNameOne, JankType::DisplayHAL,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000541 -4, 0, 0}));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800542
Alec Mouri9a29e672020-09-14 12:39:14 -0700543 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000544 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
545 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
546
Alec Mouri9a29e672020-09-14 12:39:14 -0700547 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000548 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800549 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000550 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000551 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800552 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000553 surfaceFrame1->setAcquireFenceTime(20);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800554 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000555 presentFence1->signalForTest(90);
556 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800557 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
Alec Mouri9a29e672020-09-14 12:39:14 -0700558}
559
560TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Alec Mouri363faf02021-01-29 16:34:55 -0800561 Fps refreshRate = Fps(11.0);
Alec Mouri9a29e672020-09-14 12:39:14 -0700562 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000563 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
564 sLayerNameOne,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000565 JankType::AppDeadlineMissed, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000566 25}));
Alec Mouri9a29e672020-09-14 12:39:14 -0700567 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000568 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
569 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
570
Alec Mouri9a29e672020-09-14 12:39:14 -0700571 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000572 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800573 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000574 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000575 surfaceFrame1->setAcquireFenceTime(45);
576 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri9a29e672020-09-14 12:39:14 -0700577
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800578 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
579 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000580 presentFence1->signalForTest(90);
581 mFrameTimeline->setSfPresent(86, presentFence1);
Jorim Jaggi9c03b502020-11-24 23:51:31 +0100582
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800583 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
Alec Mouri9a29e672020-09-14 12:39:14 -0700584}
585
Adithya Srinivasanead17162021-02-18 02:17:37 +0000586TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000587 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000588 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000589 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
590 sLayerNameOne,
591 JankType::SurfaceFlingerScheduling,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000592 -4, 0, -10}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000593 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000594 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
595 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
596
Adithya Srinivasanead17162021-02-18 02:17:37 +0000597 auto surfaceFrame1 =
598 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800599 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000600 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000601 surfaceFrame1->setAcquireFenceTime(50);
602 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000603
604 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
605 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000606 presentFence1->signalForTest(60);
607 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000608
609 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
610}
611
612TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000613 Fps refreshRate = Fps::fromPeriodNsecs(16);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000614 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000615 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
616 sLayerNameOne,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000617 JankType::PredictionError, -4, 5,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000618 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000619 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000620 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
621 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
622
Adithya Srinivasanead17162021-02-18 02:17:37 +0000623 auto surfaceFrame1 =
624 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800625 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000626 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000627 surfaceFrame1->setAcquireFenceTime(40);
628 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000629
630 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
631 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000632 presentFence1->signalForTest(65);
633 mFrameTimeline->setSfPresent(56, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000634
635 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
636}
637
638TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000639 Fps refreshRate = Fps::fromPeriodNsecs(32);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000640 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000641 incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
642 sLayerNameOne,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000643 JankType::BufferStuffing, -4, 0,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000644 0}));
Adithya Srinivasanead17162021-02-18 02:17:37 +0000645 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000646 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
647 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
648
Adithya Srinivasanead17162021-02-18 02:17:37 +0000649 auto surfaceFrame1 =
650 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800651 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000652 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000653 surfaceFrame1->setAcquireFenceTime(40);
654 mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000655
656 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000657 /*previousLatchTime*/ 56);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000658 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000659 presentFence1->signalForTest(90);
660 mFrameTimeline->setSfPresent(86, presentFence1);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000661
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000662 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
Adithya Srinivasanead17162021-02-18 02:17:37 +0000663}
664
Alec Mouri363faf02021-01-29 16:34:55 -0800665TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000666 Fps refreshRate = Fps::fromPeriodNsecs(11);
667 Fps renderRate = Fps::fromPeriodNsecs(30);
Alec Mouri363faf02021-01-29 16:34:55 -0800668 EXPECT_CALL(*mTimeStats,
669 incrementJankyFrames(
670 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
Adithya Srinivasan82eef322021-04-10 00:06:04 +0000671 JankType::AppDeadlineMissed, -4, 0, 25}));
Alec Mouri363faf02021-01-29 16:34:55 -0800672 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000673 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
674 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
675
Alec Mouri363faf02021-01-29 16:34:55 -0800676 auto surfaceFrame1 =
677 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -0800678 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000679 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000680 surfaceFrame1->setAcquireFenceTime(45);
681 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
Alec Mouri363faf02021-01-29 16:34:55 -0800682
683 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
684 surfaceFrame1->setRenderRate(renderRate);
685 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000686 presentFence1->signalForTest(90);
687 mFrameTimeline->setSfPresent(86, presentFence1);
Alec Mouri363faf02021-01-29 16:34:55 -0800688
689 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
690}
691
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000692TEST_F(FrameTimelineTest, presentFenceSignaled_displayFramePredictionExpiredPresentsSurfaceFrame) {
693 Fps refreshRate = Fps::fromPeriodNsecs(11);
694 Fps renderRate = Fps::fromPeriodNsecs(30);
695
696 EXPECT_CALL(*mTimeStats,
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000697 incrementJankyFrames(
698 TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
699 JankType::Unknown | JankType::AppDeadlineMissed,
Adithya Srinivasande272452021-04-10 00:21:00 +0000700 0, 0, 25}));
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000701 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
702 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
703 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
704
705 auto surfaceFrame1 =
706 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
707 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000708 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000709 surfaceFrame1->setAcquireFenceTime(45);
710 // Trigger a prediction expiry
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +0000711 flushTokens();
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000712 mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
713
714 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
715 surfaceFrame1->setRenderRate(renderRate);
716 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
717 presentFence1->signalForTest(90);
718 mFrameTimeline->setSfPresent(86, presentFence1);
719
720 auto displayFrame = getDisplayFrame(0);
721 EXPECT_EQ(displayFrame->getJankType(), JankType::Unknown);
722 EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::UnknownStart);
723 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::UnknownFinish);
724 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::UnknownPresent);
725
726 EXPECT_EQ(surfaceFrame1->getActuals().presentTime, 90);
Adithya Srinivasan8a945502021-03-19 19:12:32 +0000727 EXPECT_EQ(surfaceFrame1->getJankType(), JankType::Unknown | JankType::AppDeadlineMissed);
Adithya Srinivasan115ac692021-03-06 01:21:30 +0000728}
729
Adithya Srinivasan01189672020-10-20 14:23:05 -0700730/*
731 * Tracing Tests
732 *
733 * Trace packets are flushed all the way only when the next packet is traced.
734 * For example: trace<Display/Surface>Frame() will create a TracePacket but not flush it. Only when
735 * another TracePacket is created, the previous one is guaranteed to be flushed. The following tests
736 * will have additional empty frames created for this reason.
737 */
738TEST_F(FrameTimelineTest, tracing_noPacketsSentWithoutTraceStart) {
739 auto tracingSession = getTracingSessionForTest();
740 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700741 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000742 auto surfaceFrame1 =
743 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000744 sLayerIdOne, sLayerNameOne, sLayerNameOne,
745 /*isBuffer*/ true);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700746
747 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800748 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800749 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
750 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700751 mFrameTimeline->setSfPresent(25, presentFence1);
752 presentFence1->signalForTest(30);
753
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000754 addEmptyDisplayFrame();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700755
756 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000757 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700758}
759
760TEST_F(FrameTimelineTest, tracing_sanityTest) {
761 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800762 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -0800763 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700764 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700765
766 tracingSession->StartBlocking();
767 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
768 int64_t token2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000769 auto surfaceFrame1 =
770 mFrameTimeline->createSurfaceFrameForToken({token1, sInputEventId}, sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000771 sLayerIdOne, sLayerNameOne, sLayerNameOne,
772 /*isBuffer*/ true);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700773
774 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800775 mFrameTimeline->setSfWakeUp(token2, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800776 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
777 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700778 mFrameTimeline->setSfPresent(25, presentFence1);
779 presentFence1->signalForTest(30);
780
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000781 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000782 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700783 tracingSession->StopBlocking();
784
785 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000786 // Display Frame 1 has 8 packets - 4 from DisplayFrame and 4 from SurfaceFrame.
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000787 EXPECT_EQ(packets.size(), 8u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700788}
789
790TEST_F(FrameTimelineTest, traceDisplayFrame_invalidTokenDoesNotEmitTracePacket) {
791 auto tracingSession = getTracingSessionForTest();
792 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700793
794 tracingSession->StartBlocking();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700795
796 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800797 mFrameTimeline->setSfWakeUp(-1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700798 mFrameTimeline->setSfPresent(25, presentFence1);
799 presentFence1->signalForTest(30);
800
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000801 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000802 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700803 tracingSession->StopBlocking();
804
805 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000806 EXPECT_EQ(packets.size(), 0u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700807}
808
809TEST_F(FrameTimelineTest, traceSurfaceFrame_invalidTokenDoesNotEmitTracePacket) {
810 auto tracingSession = getTracingSessionForTest();
811 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700812
813 tracingSession->StartBlocking();
814 int64_t token1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
Alec Mouriadebf5c2021-01-05 12:57:36 -0800815 auto surfaceFrame1 =
816 mFrameTimeline->createSurfaceFrameForToken({}, sPidOne, sUidOne, sLayerIdOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +0000817 sLayerNameOne, sLayerNameOne,
818 /*isBuffer*/ true);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700819
820 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800821 mFrameTimeline->setSfWakeUp(token1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -0800822 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
823 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700824 mFrameTimeline->setSfPresent(25, presentFence1);
825 presentFence1->signalForTest(30);
826
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000827 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000828 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -0700829 tracingSession->StopBlocking();
830
831 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000832 // Display Frame 1 has 4 packets (SurfaceFrame shouldn't be traced since it has an invalid
833 // token).
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -1000834 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700835}
836
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000837ProtoExpectedDisplayFrameStart createProtoExpectedDisplayFrameStart(int64_t cookie, int64_t token,
838 pid_t pid) {
839 ProtoExpectedDisplayFrameStart proto;
840 proto.set_cookie(cookie);
841 proto.set_token(token);
842 proto.set_pid(pid);
843 return proto;
844}
845
846ProtoActualDisplayFrameStart createProtoActualDisplayFrameStart(
847 int64_t cookie, int64_t token, pid_t pid, ProtoPresentType presentType, bool onTimeFinish,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000848 bool gpuComposition, ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000849 ProtoActualDisplayFrameStart proto;
850 proto.set_cookie(cookie);
851 proto.set_token(token);
852 proto.set_pid(pid);
853 proto.set_present_type(presentType);
854 proto.set_on_time_finish(onTimeFinish);
855 proto.set_gpu_composition(gpuComposition);
856 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000857 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000858 return proto;
859}
860
861ProtoExpectedSurfaceFrameStart createProtoExpectedSurfaceFrameStart(int64_t cookie, int64_t token,
862 int64_t displayFrameToken,
863 pid_t pid,
864 std::string layerName) {
865 ProtoExpectedSurfaceFrameStart proto;
866 proto.set_cookie(cookie);
867 proto.set_token(token);
868 proto.set_display_frame_token(displayFrameToken);
869 proto.set_pid(pid);
870 proto.set_layer_name(layerName);
871 return proto;
872}
873
874ProtoActualSurfaceFrameStart createProtoActualSurfaceFrameStart(
875 int64_t cookie, int64_t token, int64_t displayFrameToken, pid_t pid, std::string layerName,
876 ProtoPresentType presentType, bool onTimeFinish, bool gpuComposition,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000877 ProtoJankType jankType, ProtoPredictionType predictionType) {
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000878 ProtoActualSurfaceFrameStart proto;
879 proto.set_cookie(cookie);
880 proto.set_token(token);
881 proto.set_display_frame_token(displayFrameToken);
882 proto.set_pid(pid);
883 proto.set_layer_name(layerName);
884 proto.set_present_type(presentType);
885 proto.set_on_time_finish(onTimeFinish);
886 proto.set_gpu_composition(gpuComposition);
887 proto.set_jank_type(jankType);
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000888 proto.set_prediction_type(predictionType);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000889 return proto;
890}
891
892ProtoFrameEnd createProtoFrameEnd(int64_t cookie) {
893 ProtoFrameEnd proto;
894 proto.set_cookie(cookie);
895 return proto;
896}
897
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000898void validateTraceEvent(const ProtoExpectedDisplayFrameStart& received,
899 const ProtoExpectedDisplayFrameStart& source) {
900 ASSERT_TRUE(received.has_cookie());
901 EXPECT_EQ(received.cookie(), source.cookie());
902
Adithya Srinivasan01189672020-10-20 14:23:05 -0700903 ASSERT_TRUE(received.has_token());
904 EXPECT_EQ(received.token(), source.token());
905
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000906 ASSERT_TRUE(received.has_pid());
907 EXPECT_EQ(received.pid(), source.pid());
908}
909
910void validateTraceEvent(const ProtoActualDisplayFrameStart& received,
911 const ProtoActualDisplayFrameStart& source) {
912 ASSERT_TRUE(received.has_cookie());
913 EXPECT_EQ(received.cookie(), source.cookie());
914
915 ASSERT_TRUE(received.has_token());
916 EXPECT_EQ(received.token(), source.token());
917
918 ASSERT_TRUE(received.has_pid());
919 EXPECT_EQ(received.pid(), source.pid());
920
Adithya Srinivasan01189672020-10-20 14:23:05 -0700921 ASSERT_TRUE(received.has_present_type());
922 EXPECT_EQ(received.present_type(), source.present_type());
923 ASSERT_TRUE(received.has_on_time_finish());
924 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
925 ASSERT_TRUE(received.has_gpu_composition());
926 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
927 ASSERT_TRUE(received.has_jank_type());
928 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000929 ASSERT_TRUE(received.has_prediction_type());
930 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700931}
932
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000933void validateTraceEvent(const ProtoExpectedSurfaceFrameStart& received,
934 const ProtoExpectedSurfaceFrameStart& source) {
935 ASSERT_TRUE(received.has_cookie());
936 EXPECT_EQ(received.cookie(), source.cookie());
937
Adithya Srinivasan01189672020-10-20 14:23:05 -0700938 ASSERT_TRUE(received.has_token());
939 EXPECT_EQ(received.token(), source.token());
940
941 ASSERT_TRUE(received.has_display_frame_token());
942 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
943
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000944 ASSERT_TRUE(received.has_pid());
945 EXPECT_EQ(received.pid(), source.pid());
946
947 ASSERT_TRUE(received.has_layer_name());
948 EXPECT_EQ(received.layer_name(), source.layer_name());
949}
950
951void validateTraceEvent(const ProtoActualSurfaceFrameStart& received,
952 const ProtoActualSurfaceFrameStart& source) {
953 ASSERT_TRUE(received.has_cookie());
954 EXPECT_EQ(received.cookie(), source.cookie());
955
956 ASSERT_TRUE(received.has_token());
957 EXPECT_EQ(received.token(), source.token());
958
959 ASSERT_TRUE(received.has_display_frame_token());
960 EXPECT_EQ(received.display_frame_token(), source.display_frame_token());
961
962 ASSERT_TRUE(received.has_pid());
963 EXPECT_EQ(received.pid(), source.pid());
964
965 ASSERT_TRUE(received.has_layer_name());
966 EXPECT_EQ(received.layer_name(), source.layer_name());
967
Adithya Srinivasan01189672020-10-20 14:23:05 -0700968 ASSERT_TRUE(received.has_present_type());
969 EXPECT_EQ(received.present_type(), source.present_type());
970 ASSERT_TRUE(received.has_on_time_finish());
971 EXPECT_EQ(received.on_time_finish(), source.on_time_finish());
972 ASSERT_TRUE(received.has_gpu_composition());
973 EXPECT_EQ(received.gpu_composition(), source.gpu_composition());
974 ASSERT_TRUE(received.has_jank_type());
975 EXPECT_EQ(received.jank_type(), source.jank_type());
Adithya Srinivasan78e58af2021-02-25 00:08:08 +0000976 ASSERT_TRUE(received.has_prediction_type());
977 EXPECT_EQ(received.prediction_type(), source.prediction_type());
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000978}
Adithya Srinivasan01189672020-10-20 14:23:05 -0700979
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000980void validateTraceEvent(const ProtoFrameEnd& received, const ProtoFrameEnd& source) {
981 ASSERT_TRUE(received.has_cookie());
982 EXPECT_EQ(received.cookie(), source.cookie());
Adithya Srinivasan01189672020-10-20 14:23:05 -0700983}
984
985TEST_F(FrameTimelineTest, traceDisplayFrame_emitsValidTracePacket) {
986 auto tracingSession = getTracingSessionForTest();
987 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan01189672020-10-20 14:23:05 -0700988
989 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +0000990 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
Adithya Srinivasan01189672020-10-20 14:23:05 -0700991
992 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -0800993 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan01189672020-10-20 14:23:05 -0700994 mFrameTimeline->setSfPresent(26, presentFence1);
995 presentFence1->signalForTest(31);
996
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +0000997 int64_t traceCookie = snoopCurrentTraceCookie();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +0000998 auto protoExpectedDisplayFrameStart =
999 createProtoExpectedDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1000 kSurfaceFlingerPid);
1001 auto protoExpectedDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1002 auto protoActualDisplayFrameStart =
1003 createProtoActualDisplayFrameStart(traceCookie + 2, displayFrameToken1,
1004 kSurfaceFlingerPid,
1005 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001006 FrameTimelineEvent::JANK_NONE,
1007 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001008 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001009
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001010 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001011 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001012 tracingSession->StopBlocking();
1013
1014 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001015 EXPECT_EQ(packets.size(), 4u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001016
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001017 // Packet - 0 : ExpectedDisplayFrameStart
1018 const auto& packet0 = packets[0];
1019 ASSERT_TRUE(packet0.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001020 EXPECT_EQ(packet0.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001021 ASSERT_TRUE(packet0.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001022
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001023 const auto& event0 = packet0.frame_timeline_event();
1024 ASSERT_TRUE(event0.has_expected_display_frame_start());
1025 const auto& expectedDisplayFrameStart = event0.expected_display_frame_start();
1026 validateTraceEvent(expectedDisplayFrameStart, protoExpectedDisplayFrameStart);
1027
1028 // Packet - 1 : FrameEnd (ExpectedDisplayFrame)
1029 const auto& packet1 = packets[1];
1030 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001031 EXPECT_EQ(packet1.timestamp(), 30u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001032 ASSERT_TRUE(packet1.has_frame_timeline_event());
1033
1034 const auto& event1 = packet1.frame_timeline_event();
1035 ASSERT_TRUE(event1.has_frame_end());
1036 const auto& expectedDisplayFrameEnd = event1.frame_end();
1037 validateTraceEvent(expectedDisplayFrameEnd, protoExpectedDisplayFrameEnd);
1038
1039 // Packet - 2 : ActualDisplayFrameStart
1040 const auto& packet2 = packets[2];
1041 ASSERT_TRUE(packet2.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001042 EXPECT_EQ(packet2.timestamp(), 20u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001043 ASSERT_TRUE(packet2.has_frame_timeline_event());
1044
1045 const auto& event2 = packet2.frame_timeline_event();
1046 ASSERT_TRUE(event2.has_actual_display_frame_start());
1047 const auto& actualDisplayFrameStart = event2.actual_display_frame_start();
1048 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1049
1050 // Packet - 3 : FrameEnd (ActualDisplayFrame)
1051 const auto& packet3 = packets[3];
1052 ASSERT_TRUE(packet3.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001053 EXPECT_EQ(packet3.timestamp(), 31u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001054 ASSERT_TRUE(packet3.has_frame_timeline_event());
1055
1056 const auto& event3 = packet3.frame_timeline_event();
1057 ASSERT_TRUE(event3.has_frame_end());
1058 const auto& actualDisplayFrameEnd = event3.frame_end();
1059 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001060}
1061
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001062TEST_F(FrameTimelineTest, traceDisplayFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1063 auto tracingSession = getTracingSessionForTest();
1064 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1065
1066 tracingSession->StartBlocking();
1067 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
1068 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001069 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001070
1071 // Set up the display frame
1072 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
1073 mFrameTimeline->setSfPresent(26, presentFence1);
1074 presentFence1->signalForTest(31);
1075
1076 int64_t traceCookie = snoopCurrentTraceCookie();
1077
1078 auto protoActualDisplayFrameStart =
1079 createProtoActualDisplayFrameStart(traceCookie + 1, displayFrameToken1,
1080 kSurfaceFlingerPid,
1081 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001082 false, FrameTimelineEvent::JANK_UNKNOWN,
1083 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001084 auto protoActualDisplayFrameEnd = createProtoFrameEnd(traceCookie + 1);
1085
1086 addEmptyDisplayFrame();
1087 flushTrace();
1088 tracingSession->StopBlocking();
1089
1090 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1091 // Only actual timeline packets should be in the trace
1092 EXPECT_EQ(packets.size(), 2u);
1093
1094 // Packet - 0 : ActualDisplayFrameStart
1095 const auto& packet0 = packets[0];
1096 ASSERT_TRUE(packet0.has_timestamp());
1097 EXPECT_EQ(packet0.timestamp(), 20u);
1098 ASSERT_TRUE(packet0.has_frame_timeline_event());
1099
1100 const auto& event0 = packet0.frame_timeline_event();
1101 ASSERT_TRUE(event0.has_actual_display_frame_start());
1102 const auto& actualDisplayFrameStart = event0.actual_display_frame_start();
1103 validateTraceEvent(actualDisplayFrameStart, protoActualDisplayFrameStart);
1104
1105 // Packet - 1 : FrameEnd (ActualDisplayFrame)
1106 const auto& packet1 = packets[1];
1107 ASSERT_TRUE(packet1.has_timestamp());
Adithya Srinivasan1a971632021-02-26 23:10:29 +00001108 EXPECT_EQ(packet1.timestamp(), 31u);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001109 ASSERT_TRUE(packet1.has_frame_timeline_event());
1110
1111 const auto& event1 = packet1.frame_timeline_event();
1112 ASSERT_TRUE(event1.has_frame_end());
1113 const auto& actualDisplayFrameEnd = event1.frame_end();
1114 validateTraceEvent(actualDisplayFrameEnd, protoActualDisplayFrameEnd);
1115}
1116
Adithya Srinivasan01189672020-10-20 14:23:05 -07001117TEST_F(FrameTimelineTest, traceSurfaceFrame_emitsValidTracePacket) {
1118 auto tracingSession = getTracingSessionForTest();
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001119 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001120 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan01189672020-10-20 14:23:05 -07001121 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1122 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1123
1124 tracingSession->StartBlocking();
1125 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 25, 40});
1126 int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({30, 35, 40});
Adithya Srinivasan01189672020-10-20 14:23:05 -07001127
1128 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001129 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001130 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001131 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001132 auto surfaceFrame2 =
1133 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001134 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001135 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001136 surfaceFrame1->setActualQueueTime(10);
1137 surfaceFrame1->setDropTime(15);
1138
1139 surfaceFrame2->setActualQueueTime(15);
1140 surfaceFrame2->setAcquireFenceTime(20);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001141
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001142 // First 2 cookies will be used by the DisplayFrame
1143 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1144
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001145 auto protoDroppedSurfaceFrameExpectedStart =
1146 createProtoExpectedSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1147 displayFrameToken1, sPidOne, sLayerNameOne);
1148 auto protoDroppedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 1);
1149 auto protoDroppedSurfaceFrameActualStart =
1150 createProtoActualSurfaceFrameStart(traceCookie + 2, surfaceFrameToken,
1151 displayFrameToken1, sPidOne, sLayerNameOne,
1152 FrameTimelineEvent::PRESENT_DROPPED, false, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001153 FrameTimelineEvent::JANK_NONE,
1154 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001155 auto protoDroppedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 2);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001156
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001157 auto protoPresentedSurfaceFrameExpectedStart =
1158 createProtoExpectedSurfaceFrameStart(traceCookie + 3, surfaceFrameToken,
1159 displayFrameToken1, sPidOne, sLayerNameOne);
1160 auto protoPresentedSurfaceFrameExpectedEnd = createProtoFrameEnd(traceCookie + 3);
1161 auto protoPresentedSurfaceFrameActualStart =
1162 createProtoActualSurfaceFrameStart(traceCookie + 4, surfaceFrameToken,
1163 displayFrameToken1, sPidOne, sLayerNameOne,
1164 FrameTimelineEvent::PRESENT_ON_TIME, true, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001165 FrameTimelineEvent::JANK_NONE,
1166 FrameTimelineEvent::PREDICTION_VALID);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001167 auto protoPresentedSurfaceFrameActualEnd = createProtoFrameEnd(traceCookie + 4);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001168
1169 // Set up the display frame
Alec Mouri7d436ec2021-01-27 20:40:50 -08001170 mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001171 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1172 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001173 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001174 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001175 mFrameTimeline->setSfPresent(26, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001176 presentFence1->signalForTest(40);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001177
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001178 addEmptyDisplayFrame();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001179 flushTrace();
Adithya Srinivasan01189672020-10-20 14:23:05 -07001180 tracingSession->StopBlocking();
1181
1182 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001183 // 4 DisplayFrame + 4 DroppedSurfaceFrame + 4 PresentedSurfaceFrame
1184 EXPECT_EQ(packets.size(), 12u);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001185
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001186 // Packet - 4 : ExpectedSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001187 const auto& packet4 = packets[4];
1188 ASSERT_TRUE(packet4.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001189 EXPECT_EQ(packet4.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001190 ASSERT_TRUE(packet4.has_frame_timeline_event());
Adithya Srinivasan01189672020-10-20 14:23:05 -07001191
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001192 const auto& event4 = packet4.frame_timeline_event();
1193 ASSERT_TRUE(event4.has_expected_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001194 const auto& expectedSurfaceFrameStart1 = event4.expected_surface_frame_start();
1195 validateTraceEvent(expectedSurfaceFrameStart1, protoDroppedSurfaceFrameExpectedStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001196
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001197 // Packet - 5 : FrameEnd (ExpectedSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001198 const auto& packet5 = packets[5];
1199 ASSERT_TRUE(packet5.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001200 EXPECT_EQ(packet5.timestamp(), 25u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001201 ASSERT_TRUE(packet5.has_frame_timeline_event());
1202
1203 const auto& event5 = packet5.frame_timeline_event();
1204 ASSERT_TRUE(event5.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001205 const auto& expectedSurfaceFrameEnd1 = event5.frame_end();
1206 validateTraceEvent(expectedSurfaceFrameEnd1, protoDroppedSurfaceFrameExpectedEnd);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001207
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001208 // Packet - 6 : ActualSurfaceFrameStart1
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001209 const auto& packet6 = packets[6];
1210 ASSERT_TRUE(packet6.has_timestamp());
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001211 EXPECT_EQ(packet6.timestamp(), 10u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001212 ASSERT_TRUE(packet6.has_frame_timeline_event());
1213
1214 const auto& event6 = packet6.frame_timeline_event();
1215 ASSERT_TRUE(event6.has_actual_surface_frame_start());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001216 const auto& actualSurfaceFrameStart1 = event6.actual_surface_frame_start();
1217 validateTraceEvent(actualSurfaceFrameStart1, protoDroppedSurfaceFrameActualStart);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001218
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001219 // Packet - 7 : FrameEnd (ActualSurfaceFrame1)
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001220 const auto& packet7 = packets[7];
1221 ASSERT_TRUE(packet7.has_timestamp());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001222 EXPECT_EQ(packet7.timestamp(), 15u);
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001223 ASSERT_TRUE(packet7.has_frame_timeline_event());
1224
1225 const auto& event7 = packet7.frame_timeline_event();
1226 ASSERT_TRUE(event7.has_frame_end());
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001227 const auto& actualSurfaceFrameEnd1 = event7.frame_end();
1228 validateTraceEvent(actualSurfaceFrameEnd1, protoDroppedSurfaceFrameActualEnd);
1229
1230 // Packet - 8 : ExpectedSurfaceFrameStart2
1231 const auto& packet8 = packets[8];
1232 ASSERT_TRUE(packet8.has_timestamp());
1233 EXPECT_EQ(packet8.timestamp(), 10u);
1234 ASSERT_TRUE(packet8.has_frame_timeline_event());
1235
1236 const auto& event8 = packet8.frame_timeline_event();
1237 ASSERT_TRUE(event8.has_expected_surface_frame_start());
1238 const auto& expectedSurfaceFrameStart2 = event8.expected_surface_frame_start();
1239 validateTraceEvent(expectedSurfaceFrameStart2, protoPresentedSurfaceFrameExpectedStart);
1240
1241 // Packet - 9 : FrameEnd (ExpectedSurfaceFrame2)
1242 const auto& packet9 = packets[9];
1243 ASSERT_TRUE(packet9.has_timestamp());
1244 EXPECT_EQ(packet9.timestamp(), 25u);
1245 ASSERT_TRUE(packet9.has_frame_timeline_event());
1246
1247 const auto& event9 = packet9.frame_timeline_event();
1248 ASSERT_TRUE(event9.has_frame_end());
1249 const auto& expectedSurfaceFrameEnd2 = event9.frame_end();
1250 validateTraceEvent(expectedSurfaceFrameEnd2, protoPresentedSurfaceFrameExpectedEnd);
1251
1252 // Packet - 10 : ActualSurfaceFrameStart2
1253 const auto& packet10 = packets[10];
1254 ASSERT_TRUE(packet10.has_timestamp());
1255 EXPECT_EQ(packet10.timestamp(), 10u);
1256 ASSERT_TRUE(packet10.has_frame_timeline_event());
1257
1258 const auto& event10 = packet10.frame_timeline_event();
1259 ASSERT_TRUE(event10.has_actual_surface_frame_start());
1260 const auto& actualSurfaceFrameStart2 = event10.actual_surface_frame_start();
1261 validateTraceEvent(actualSurfaceFrameStart2, protoPresentedSurfaceFrameActualStart);
1262
1263 // Packet - 11 : FrameEnd (ActualSurfaceFrame2)
1264 const auto& packet11 = packets[11];
1265 ASSERT_TRUE(packet11.has_timestamp());
1266 EXPECT_EQ(packet11.timestamp(), 20u);
1267 ASSERT_TRUE(packet11.has_frame_timeline_event());
1268
1269 const auto& event11 = packet11.frame_timeline_event();
1270 ASSERT_TRUE(event11.has_frame_end());
1271 const auto& actualSurfaceFrameEnd2 = event11.frame_end();
1272 validateTraceEvent(actualSurfaceFrameEnd2, protoPresentedSurfaceFrameActualEnd);
1273}
1274
1275TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDoesNotTraceExpectedTimeline) {
1276 auto tracingSession = getTracingSessionForTest();
1277 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1278
1279 tracingSession->StartBlocking();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001280 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1281 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1282 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001283 int64_t surfaceFrameToken =
1284 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1285
1286 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001287 flushTokens();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001288 auto surfaceFrame1 =
1289 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0},
Alec Mouriadebf5c2021-01-05 12:57:36 -08001290 sPidOne, sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001291 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001292 surfaceFrame1->setActualQueueTime(appEndTime);
1293 surfaceFrame1->setAcquireFenceTime(appEndTime);
1294
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001295 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
1296 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1297 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001298 int64_t displayFrameToken =
1299 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1300
1301 // First 2 cookies will be used by the DisplayFrame
1302 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1303
1304 auto protoActualSurfaceFrameStart =
1305 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1306 displayFrameToken, sPidOne, sLayerNameOne,
1307 FrameTimelineEvent::PRESENT_UNSPECIFIED, false,
Adithya Srinivasan78e58af2021-02-25 00:08:08 +00001308 false, FrameTimelineEvent::JANK_UNKNOWN,
1309 FrameTimelineEvent::PREDICTION_EXPIRED);
Adithya Srinivasan061c14c2021-02-11 01:19:47 +00001310 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1311
1312 // Set up the display frame
1313 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1314 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1315 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1316 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1317 presentFence1->signalForTest(sfPresentTime);
1318
1319 addEmptyDisplayFrame();
1320 flushTrace();
1321 tracingSession->StopBlocking();
1322
1323 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1324 // Display Frame 4 packets + SurfaceFrame 2 packets
1325 ASSERT_EQ(packets.size(), 6u);
1326
1327 // Packet - 4 : ActualSurfaceFrameStart
1328 const auto& packet4 = packets[4];
1329 ASSERT_TRUE(packet4.has_timestamp());
1330 EXPECT_EQ(packet4.timestamp(),
1331 static_cast<uint64_t>(appEndTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1332 ASSERT_TRUE(packet4.has_frame_timeline_event());
1333
1334 const auto& event4 = packet4.frame_timeline_event();
1335 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1336 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1337 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1338
1339 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1340 const auto& packet5 = packets[5];
1341 ASSERT_TRUE(packet5.has_timestamp());
1342 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(appEndTime));
1343 ASSERT_TRUE(packet5.has_frame_timeline_event());
1344
1345 const auto& event5 = packet5.frame_timeline_event();
1346 ASSERT_TRUE(event5.has_frame_end());
1347 const auto& actualSurfaceFrameEnd = event5.frame_end();
Adithya Srinivasan05bd2d12021-01-11 18:49:58 +00001348 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
Adithya Srinivasan01189672020-10-20 14:23:05 -07001349}
1350
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001351TEST_F(FrameTimelineTest, traceSurfaceFrame_predictionExpiredDroppedFramesTracedProperly) {
1352 auto tracingSession = getTracingSessionForTest();
1353 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1354
1355 tracingSession->StartBlocking();
1356 constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
1357 constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
1358 constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
1359 int64_t surfaceFrameToken =
1360 mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
1361
1362 // Flush the token so that it would expire
Adithya Srinivasanbed4c4f2021-05-03 20:24:46 +00001363 flushTokens();
Adithya Srinivasanb2283c32021-04-21 21:31:56 +00001364 auto surfaceFrame1 =
1365 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, /*inputEventId*/ 0},
1366 sPidOne, sUidOne, sLayerIdOne, sLayerNameOne,
1367 sLayerNameOne, /*isBuffer*/ true);
1368
1369 constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(22ms).count();
1370 constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
1371 constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
1372 int64_t displayFrameToken =
1373 mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
1374
1375 // First 2 cookies will be used by the DisplayFrame
1376 int64_t traceCookie = snoopCurrentTraceCookie() + 2;
1377
1378 auto protoActualSurfaceFrameStart =
1379 createProtoActualSurfaceFrameStart(traceCookie + 1, surfaceFrameToken,
1380 displayFrameToken, sPidOne, sLayerNameOne,
1381 FrameTimelineEvent::PRESENT_DROPPED, false, false,
1382 FrameTimelineEvent::JANK_NONE,
1383 FrameTimelineEvent::PREDICTION_EXPIRED);
1384 auto protoActualSurfaceFrameEnd = createProtoFrameEnd(traceCookie + 1);
1385
1386 // Set up the display frame
1387 mFrameTimeline->setSfWakeUp(displayFrameToken, sfStartTime, Fps::fromPeriodNsecs(11));
1388 surfaceFrame1->setDropTime(sfStartTime);
1389 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Dropped);
1390 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1391 mFrameTimeline->setSfPresent(sfEndTime, presentFence1);
1392 presentFence1->signalForTest(sfPresentTime);
1393
1394 addEmptyDisplayFrame();
1395 flushTrace();
1396 tracingSession->StopBlocking();
1397
1398 auto packets = readFrameTimelinePacketsBlocking(tracingSession.get());
1399 // Display Frame 4 packets + SurfaceFrame 2 packets
1400 ASSERT_EQ(packets.size(), 6u);
1401
1402 // Packet - 4 : ActualSurfaceFrameStart
1403 const auto& packet4 = packets[4];
1404 ASSERT_TRUE(packet4.has_timestamp());
1405 EXPECT_EQ(packet4.timestamp(),
1406 static_cast<uint64_t>(sfStartTime - SurfaceFrame::kPredictionExpiredStartTimeDelta));
1407 ASSERT_TRUE(packet4.has_frame_timeline_event());
1408
1409 const auto& event4 = packet4.frame_timeline_event();
1410 ASSERT_TRUE(event4.has_actual_surface_frame_start());
1411 const auto& actualSurfaceFrameStart = event4.actual_surface_frame_start();
1412 validateTraceEvent(actualSurfaceFrameStart, protoActualSurfaceFrameStart);
1413
1414 // Packet - 5 : FrameEnd (ActualSurfaceFrame)
1415 const auto& packet5 = packets[5];
1416 ASSERT_TRUE(packet5.has_timestamp());
1417 EXPECT_EQ(packet5.timestamp(), static_cast<uint64_t>(sfStartTime));
1418 ASSERT_TRUE(packet5.has_frame_timeline_event());
1419
1420 const auto& event5 = packet5.frame_timeline_event();
1421 ASSERT_TRUE(event5.has_frame_end());
1422 const auto& actualSurfaceFrameEnd = event5.frame_end();
1423 validateTraceEvent(actualSurfaceFrameEnd, protoActualSurfaceFrameEnd);
1424}
1425
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001426// Tests for Jank classification
1427TEST_F(FrameTimelineTest, jankClassification_presentOnTimeDoesNotClassify) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001428 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001429 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001430 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1431 int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001432 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001433 auto surfaceFrame =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001434 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001435 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001436 sLayerNameOne, /*isBuffer*/ true);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001437 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001438 surfaceFrame->setPresentState(SurfaceFrame::PresentState::Presented);
1439 mFrameTimeline->addSurfaceFrame(surfaceFrame);
1440 mFrameTimeline->setSfPresent(26, presentFence1);
1441 auto displayFrame = getDisplayFrame(0);
1442 auto& presentedSurfaceFrame = getSurfaceFrame(0, 0);
1443 presentFence1->signalForTest(29);
1444
1445 // Fences haven't been flushed yet, so it should be 0
1446 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1447 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 0);
1448
1449 addEmptyDisplayFrame();
1450 displayFrame = getDisplayFrame(0);
1451
1452 // Fences have flushed, so the present timestamps should be updated
1453 EXPECT_EQ(displayFrame->getActuals().presentTime, 29);
1454 EXPECT_EQ(presentedSurfaceFrame.getActuals().presentTime, 29);
1455 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1456 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1457 EXPECT_EQ(displayFrame->getJankType(), JankType::None);
1458}
1459
1460TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001461 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001462 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001463 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1464 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001465 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001466 mFrameTimeline->setSfPresent(26, presentFence1);
1467 auto displayFrame = getDisplayFrame(0);
1468 presentFence1->signalForTest(30);
1469
1470 // Fences for the first frame haven't been flushed yet, so it should be 0
1471 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1472
1473 // Trigger a flush by finalizing the next DisplayFrame
1474 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001475 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001476 mFrameTimeline->setSfPresent(56, presentFence2);
1477 displayFrame = getDisplayFrame(0);
1478
1479 // Fences for the first frame have flushed, so the present timestamps should be updated
1480 EXPECT_EQ(displayFrame->getActuals().presentTime, 30);
1481 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1482 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1483 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1484
1485 // Fences for the second frame haven't been flushed yet, so it should be 0
1486 auto displayFrame2 = getDisplayFrame(1);
1487 presentFence2->signalForTest(65);
1488 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001489 addEmptyDisplayFrame();
1490 displayFrame2 = getDisplayFrame(1);
1491
1492 // Fences for the second frame have flushed, so the present timestamps should be updated
1493 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1494 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1495 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1496 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1497}
1498
1499TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001500 Fps vsyncRate = Fps::fromPeriodNsecs(11);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001501 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001502 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1503 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Alec Mouri363faf02021-01-29 16:34:55 -08001504 mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001505 mFrameTimeline->setSfPresent(26, presentFence1);
1506 auto displayFrame = getDisplayFrame(0);
1507 presentFence1->signalForTest(50);
1508
1509 // Fences for the first frame haven't been flushed yet, so it should be 0
1510 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1511
1512 // Trigger a flush by finalizing the next DisplayFrame
1513 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Alec Mouri363faf02021-01-29 16:34:55 -08001514 mFrameTimeline->setSfWakeUp(sfToken2, 52, vsyncRate);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001515 mFrameTimeline->setSfPresent(56, presentFence2);
1516 displayFrame = getDisplayFrame(0);
1517
1518 // Fences for the first frame have flushed, so the present timestamps should be updated
1519 EXPECT_EQ(displayFrame->getActuals().presentTime, 50);
1520 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1521 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1522 EXPECT_EQ(displayFrame->getJankType(), JankType::DisplayHAL);
1523
1524 // Fences for the second frame haven't been flushed yet, so it should be 0
1525 auto displayFrame2 = getDisplayFrame(1);
1526 presentFence2->signalForTest(75);
1527 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1528
1529 addEmptyDisplayFrame();
1530 displayFrame2 = getDisplayFrame(1);
1531
1532 // Fences for the second frame have flushed, so the present timestamps should be updated
1533 EXPECT_EQ(displayFrame2->getActuals().presentTime, 75);
1534 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1535 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1536 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1537}
1538
1539TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishEarlyPresent) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001540 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1541 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({12, 18, 40});
Alec Mouri7d436ec2021-01-27 20:40:50 -08001542 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001543
1544 mFrameTimeline->setSfPresent(22, presentFence1);
1545 auto displayFrame = getDisplayFrame(0);
1546 presentFence1->signalForTest(28);
1547
1548 // Fences haven't been flushed yet, so it should be 0
1549 EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
1550
1551 addEmptyDisplayFrame();
1552 displayFrame = getDisplayFrame(0);
1553
1554 // Fences have flushed, so the present timestamps should be updated
1555 EXPECT_EQ(displayFrame->getActuals().presentTime, 28);
1556 EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1557 EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1558 EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
1559}
1560
1561TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent) {
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001562 /*
1563 * Case 1 - cpu time > vsync period but combined time > deadline > deadline -> cpudeadlinemissed
1564 * Case 2 - cpu time < vsync period but combined time > deadline -> gpudeadlinemissed
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001565 * Case 3 - previous frame ran longer -> sf_stuffing
1566 * Case 4 - Long cpu under SF stuffing -> cpudeadlinemissed
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001567 */
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001568 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001569 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001570 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1571 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001572 auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1573 auto gpuFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001574 auto gpuFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1575 auto gpuFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001576 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001577 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001578 int64_t sfToken3 = mTokenManager->generateTokenForPredictions({82, 90, 90});
1579 int64_t sfToken4 = mTokenManager->generateTokenForPredictions({112, 120, 120});
1580
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001581 // case 1 - cpu time = 33 - 12 = 21, vsync period = 11
Alec Mouri7d436ec2021-01-27 20:40:50 -08001582 mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001583 mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
1584 auto displayFrame0 = getDisplayFrame(0);
1585 gpuFence1->signalForTest(36);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001586 presentFence1->signalForTest(52);
1587
1588 // Fences haven't been flushed yet, so it should be 0
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001589 EXPECT_EQ(displayFrame0->getActuals().presentTime, 0);
1590
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001591 // case 2 - cpu time = 56 - 52 = 4, vsync period = 30
1592 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001593 mFrameTimeline->setSfPresent(56, presentFence2, gpuFence2);
1594 auto displayFrame1 = getDisplayFrame(1);
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001595 gpuFence2->signalForTest(76);
1596 presentFence2->signalForTest(90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001597
1598 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1599 // Fences have flushed for first displayFrame, so the present timestamps should be updated
1600 EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
1601 EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1602 EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1603 EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001604
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001605 // case 3 - cpu time = 86 - 82 = 4, vsync period = 30
1606 mFrameTimeline->setSfWakeUp(sfToken3, 106, Fps::fromPeriodNsecs(30));
1607 mFrameTimeline->setSfPresent(112, presentFence3, gpuFence3);
1608 auto displayFrame2 = getDisplayFrame(2);
1609 gpuFence3->signalForTest(116);
1610 presentFence3->signalForTest(120);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001611
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001612 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001613 // Fences have flushed for second displayFrame, so the present timestamps should be updated
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001614 EXPECT_EQ(displayFrame1->getActuals().presentTime, 90);
Adithya Srinivasan36b01af2021-04-07 22:29:47 +00001615 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1616 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1617 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001618
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001619 // case 4 - cpu time = 86 - 82 = 4, vsync period = 30
1620 mFrameTimeline->setSfWakeUp(sfToken4, 120, Fps::fromPeriodNsecs(30));
1621 mFrameTimeline->setSfPresent(140, presentFence4, gpuFence4);
1622 auto displayFrame3 = getDisplayFrame(3);
1623 gpuFence4->signalForTest(156);
1624 presentFence4->signalForTest(180);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001625
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001626 EXPECT_EQ(displayFrame3->getActuals().presentTime, 0);
1627 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1628 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1629 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1630 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1631 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerStuffing);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001632
1633 addEmptyDisplayFrame();
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001634
Adithya Srinivasan57dc81d2021-04-14 17:31:41 +00001635 // Fences have flushed for third displayFrame, so the present timestamps should be updated
1636 EXPECT_EQ(displayFrame3->getActuals().presentTime, 180);
1637 EXPECT_EQ(displayFrame3->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1638 EXPECT_EQ(displayFrame3->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1639 EXPECT_EQ(displayFrame3->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001640}
1641
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001642TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001643 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001644 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001645 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1646 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001647 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1648 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1649 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001650 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001651 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001652 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001653 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001654 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001655 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1656 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001657 mFrameTimeline->setSfPresent(27, presentFence1);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001658 auto displayFrame1 = getDisplayFrame(0);
1659 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1660 presentFence1->signalForTest(30);
1661
1662 // Fences for the first frame haven't been flushed yet, so it should be 0
1663 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1664 auto actuals1 = presentedSurfaceFrame1.getActuals();
1665 EXPECT_EQ(actuals1.presentTime, 0);
1666
1667 // Trigger a flush by finalizing the next DisplayFrame
1668 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1669 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001670 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001671 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001672 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001673 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001674 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001675 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1676 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001677 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001678 auto displayFrame2 = getDisplayFrame(1);
1679 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1680
1681 // Fences for the first frame have flushed, so the present timestamps should be updated
1682 EXPECT_EQ(displayFrame1->getActuals().presentTime, 30);
1683 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1684 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1685 EXPECT_EQ(displayFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
1686
1687 actuals1 = presentedSurfaceFrame1.getActuals();
1688 EXPECT_EQ(actuals1.presentTime, 30);
1689 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1690 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1691 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::SurfaceFlingerScheduling);
1692
1693 // Fences for the second frame haven't been flushed yet, so it should be 0
1694 presentFence2->signalForTest(65);
1695 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1696 auto actuals2 = presentedSurfaceFrame2.getActuals();
1697 EXPECT_EQ(actuals2.presentTime, 0);
1698
Alec Mouri363faf02021-01-29 16:34:55 -08001699 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1700
1701 EXPECT_CALL(*mTimeStats,
1702 incrementJankyFrames(
1703 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
Adithya Srinivasan82eef322021-04-10 00:06:04 +00001704 sLayerNameOne, JankType::PredictionError, -3, 5,
Alec Mouri363faf02021-01-29 16:34:55 -08001705 0}));
1706
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001707 addEmptyDisplayFrame();
1708
1709 // Fences for the second frame have flushed, so the present timestamps should be updated
1710 EXPECT_EQ(displayFrame2->getActuals().presentTime, 65);
1711 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1712 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1713 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1714
1715 actuals2 = presentedSurfaceFrame2.getActuals();
1716 EXPECT_EQ(actuals2.presentTime, 65);
1717 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1718 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1719 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1720}
1721
1722TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001723 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001724 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001725 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
1726 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001727 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
1728 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
1729 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001730 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001731 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001732 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001733 surfaceFrame1->setAcquireFenceTime(16);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001734 mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001735 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1736 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1737 mFrameTimeline->setSfPresent(26, presentFence1);
1738 auto displayFrame1 = getDisplayFrame(0);
1739 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1740 presentFence1->signalForTest(50);
1741
1742 // Fences for the first frame haven't been flushed yet, so it should be 0
1743 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1744 auto actuals1 = presentedSurfaceFrame1.getActuals();
1745 EXPECT_EQ(actuals1.presentTime, 0);
1746
1747 // Trigger a flush by finalizing the next DisplayFrame
1748 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1749 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001750 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001751 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001752 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001753 surfaceFrame2->setAcquireFenceTime(36);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001754 mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001755 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1756 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001757 mFrameTimeline->setSfPresent(57, presentFence2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001758 auto displayFrame2 = getDisplayFrame(1);
1759 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1760
1761 // Fences for the first frame have flushed, so the present timestamps should be updated
1762 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1763 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1764 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1765 EXPECT_EQ(displayFrame1->getJankType(), JankType::DisplayHAL);
1766
1767 actuals1 = presentedSurfaceFrame1.getActuals();
1768 EXPECT_EQ(actuals1.presentTime, 50);
1769 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1770 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1771 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::DisplayHAL);
1772
1773 // Fences for the second frame haven't been flushed yet, so it should be 0
1774 presentFence2->signalForTest(86);
1775 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1776 auto actuals2 = presentedSurfaceFrame2.getActuals();
1777 EXPECT_EQ(actuals2.presentTime, 0);
1778
Alec Mouri363faf02021-01-29 16:34:55 -08001779 ::testing::Mock::VerifyAndClearExpectations(mTimeStats.get());
1780
1781 EXPECT_CALL(*mTimeStats,
1782 incrementJankyFrames(
1783 TimeStats::JankyFramesInfo{Fps::fromPeriodNsecs(11), std::nullopt, sUidOne,
Adithya Srinivasan82eef322021-04-10 00:06:04 +00001784 sLayerNameOne, JankType::PredictionError, -3, 5,
Alec Mouri363faf02021-01-29 16:34:55 -08001785 0}));
1786
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001787 addEmptyDisplayFrame();
1788
1789 // Fences for the second frame have flushed, so the present timestamps should be updated
1790 EXPECT_EQ(displayFrame2->getActuals().presentTime, 86);
1791 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1792 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1793 EXPECT_EQ(displayFrame2->getJankType(), JankType::PredictionError);
1794
1795 actuals2 = presentedSurfaceFrame2.getActuals();
1796 EXPECT_EQ(actuals2.presentTime, 86);
1797 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1798 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1799 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::PredictionError);
1800}
1801
1802TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishEarlyPresent) {
Alec Mouri363faf02021-01-29 16:34:55 -08001803 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
Alec Mouri7d436ec2021-01-27 20:40:50 -08001804
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001805 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001806 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001807 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
1808 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001809 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001810 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001811 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001812 surfaceFrame1->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001813 mFrameTimeline->setSfWakeUp(sfToken1, 42, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001814 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1815 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1816 mFrameTimeline->setSfPresent(46, presentFence1);
1817 auto displayFrame1 = getDisplayFrame(0);
1818 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1819 presentFence1->signalForTest(50);
1820
1821 // Fences for the first frame haven't been flushed yet, so it should be 0
1822 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1823 auto actuals1 = presentedSurfaceFrame1.getActuals();
1824 EXPECT_EQ(actuals1.presentTime, 0);
1825
1826 addEmptyDisplayFrame();
1827
1828 // Fences for the first frame have flushed, so the present timestamps should be updated
1829 EXPECT_EQ(displayFrame1->getActuals().presentTime, 50);
1830 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1831 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1832 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1833
1834 actuals1 = presentedSurfaceFrame1.getActuals();
1835 EXPECT_EQ(actuals1.presentTime, 50);
1836 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::EarlyPresent);
1837 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1838 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::Unknown);
1839}
1840
1841TEST_F(FrameTimelineTest, jankClassification_surfaceFrameLateFinishLatePresent) {
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001842 // First frame - DisplayFrame is not janky. This should classify the SurfaceFrame as only
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001843 // AppDeadlineMissed. Second frame - DisplayFrame is janky. This should propagate DisplayFrame's
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001844 // jank to the SurfaceFrame along with AppDeadlineMissed.
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001845
Alec Mouri363faf02021-01-29 16:34:55 -08001846 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001847 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001848 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
1849 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001850 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
1851 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
1852 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001853 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001854 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001855 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001856 surfaceFrame1->setAcquireFenceTime(26);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001857 mFrameTimeline->setSfWakeUp(sfToken1, 32, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001858 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1859 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1860 mFrameTimeline->setSfPresent(36, presentFence1);
1861 auto displayFrame1 = getDisplayFrame(0);
1862 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1863 presentFence1->signalForTest(40);
1864
1865 // Fences for the first frame haven't been flushed yet, so it should be 0
1866 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1867 auto actuals1 = presentedSurfaceFrame1.getActuals();
1868 EXPECT_EQ(actuals1.presentTime, 0);
1869
1870 // Trigger a flush by finalizing the next DisplayFrame
1871 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1872 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001873 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001874 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001875 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001876 surfaceFrame2->setAcquireFenceTime(40);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001877 mFrameTimeline->setSfWakeUp(sfToken2, 43, Fps::fromPeriodNsecs(11));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001878 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
1879 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1880 mFrameTimeline->setSfPresent(56, presentFence2);
1881 auto displayFrame2 = getDisplayFrame(1);
1882 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1883
1884 // Fences for the first frame have flushed, so the present timestamps should be updated
1885 EXPECT_EQ(displayFrame1->getActuals().presentTime, 40);
1886 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1887 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1888 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1889
1890 actuals1 = presentedSurfaceFrame1.getActuals();
1891 EXPECT_EQ(actuals1.presentTime, 40);
1892 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1893 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1894 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1895
1896 // Fences for the second frame haven't been flushed yet, so it should be 0
1897 presentFence2->signalForTest(60);
1898 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1899 auto actuals2 = presentedSurfaceFrame2.getActuals();
1900 EXPECT_EQ(actuals2.presentTime, 0);
1901
1902 addEmptyDisplayFrame();
1903
1904 // Fences for the second frame have flushed, so the present timestamps should be updated
1905 EXPECT_EQ(displayFrame2->getActuals().presentTime, 60);
1906 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1907 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1908 EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
1909
1910 actuals2 = presentedSurfaceFrame2.getActuals();
1911 EXPECT_EQ(actuals2.presentTime, 60);
1912 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1913 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
Adithya Srinivasan8a945502021-03-19 19:12:32 +00001914 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
1915 JankType::SurfaceFlingerCpuDeadlineMissed | JankType::AppDeadlineMissed);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001916}
1917
1918TEST_F(FrameTimelineTest, jankClassification_multiJankBufferStuffingAndAppDeadlineMissed) {
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001919 // Layer specific increment
Alec Mouri363faf02021-01-29 16:34:55 -08001920 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001921 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1922 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
1923 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
1924
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001925 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
1926 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001927 auto surfaceFrame1 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001928 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001929 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001930 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001931 surfaceFrame1->setAcquireFenceTime(50);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001932 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001933 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
1934 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
1935 mFrameTimeline->setSfPresent(56, presentFence1);
1936 auto displayFrame1 = getDisplayFrame(0);
1937 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
1938 presentFence1->signalForTest(60);
1939
1940 // Fences for the first frame haven't been flushed yet, so it should be 0
1941 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
1942 auto actuals1 = presentedSurfaceFrame1.getActuals();
1943 EXPECT_EQ(actuals1.presentTime, 0);
1944
1945 // Trigger a flush by finalizing the next DisplayFrame
1946 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
1947 auto surfaceFrame2 =
Siarhei Vishniakoufc434ac2021-01-13 10:28:00 -10001948 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
Alec Mouriadebf5c2021-01-05 12:57:36 -08001949 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00001950 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001951 surfaceFrame2->setAcquireFenceTime(84);
Alec Mouri7d436ec2021-01-27 20:40:50 -08001952 mFrameTimeline->setSfWakeUp(sfToken2, 112, Fps::fromPeriodNsecs(30));
Adithya Srinivasan9b2ca3e2020-11-10 10:14:17 -08001953 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
1954 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
1955 mFrameTimeline->setSfPresent(116, presentFence2);
1956 auto displayFrame2 = getDisplayFrame(1);
1957 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
1958 presentFence2->signalForTest(120);
1959
1960 // Fences for the first frame have flushed, so the present timestamps should be updated
1961 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
1962 actuals1 = presentedSurfaceFrame1.getActuals();
1963 EXPECT_EQ(actuals1.endTime, 50);
1964 EXPECT_EQ(actuals1.presentTime, 60);
1965
1966 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1967 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1968 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
1969
1970 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1971 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1972 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
1973
1974 // Fences for the second frame haven't been flushed yet, so it should be 0
1975 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
1976 auto actuals2 = presentedSurfaceFrame2.getActuals();
1977 EXPECT_EQ(actuals2.presentTime, 0);
1978
1979 addEmptyDisplayFrame();
1980
1981 // Fences for the second frame have flushed, so the present timestamps should be updated
1982 EXPECT_EQ(displayFrame2->getActuals().presentTime, 120);
1983 actuals2 = presentedSurfaceFrame2.getActuals();
1984 EXPECT_EQ(actuals2.presentTime, 120);
1985
1986 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
1987 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
1988 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
1989
1990 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
1991 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
1992 EXPECT_EQ(presentedSurfaceFrame2.getJankType(),
1993 JankType::AppDeadlineMissed | JankType::BufferStuffing);
1994}
Alec Mouriadebf5c2021-01-05 12:57:36 -08001995
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00001996TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
1997 // Layer specific increment
1998 EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
1999 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2000 int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
2001 int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
2002
2003 int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
2004 int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
2005 auto surfaceFrame1 =
2006 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
2007 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002008 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002009 surfaceFrame1->setAcquireFenceTime(50);
2010 mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
2011 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2012 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2013 mFrameTimeline->setSfPresent(56, presentFence1);
2014 auto displayFrame1 = getDisplayFrame(0);
2015 auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
2016 presentFence1->signalForTest(60);
2017
2018 // Fences for the first frame haven't been flushed yet, so it should be 0
2019 EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
2020 auto actuals1 = presentedSurfaceFrame1.getActuals();
2021 EXPECT_EQ(actuals1.presentTime, 0);
2022
2023 // Trigger a flush by finalizing the next DisplayFrame
2024 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2025 auto surfaceFrame2 =
2026 mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
2027 sUidOne, sLayerIdOne, sLayerNameOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002028 sLayerNameOne, /*isBuffer*/ true);
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002029 surfaceFrame2->setAcquireFenceTime(80);
2030 mFrameTimeline->setSfWakeUp(sfToken2, 82, Fps::fromPeriodNsecs(30));
2031 // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
2032 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
2033 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2034 mFrameTimeline->setSfPresent(86, presentFence2);
2035 auto displayFrame2 = getDisplayFrame(1);
2036 auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
2037 presentFence2->signalForTest(90);
2038
2039 // Fences for the first frame have flushed, so the present timestamps should be updated
2040 EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
2041 actuals1 = presentedSurfaceFrame1.getActuals();
2042 EXPECT_EQ(actuals1.endTime, 50);
2043 EXPECT_EQ(actuals1.presentTime, 60);
2044
2045 EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2046 EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2047 EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
2048
2049 EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2050 EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
2051 EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
2052
2053 // Fences for the second frame haven't been flushed yet, so it should be 0
2054 EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
2055 auto actuals2 = presentedSurfaceFrame2.getActuals();
2056 EXPECT_EQ(actuals2.presentTime, 0);
2057
2058 addEmptyDisplayFrame();
2059
2060 // Fences for the second frame have flushed, so the present timestamps should be updated
2061 EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
2062 actuals2 = presentedSurfaceFrame2.getActuals();
2063 EXPECT_EQ(actuals2.presentTime, 90);
2064
2065 EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
2066 EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2067 EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
2068
2069 EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
2070 EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
2071 EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
2072}
2073
Alec Mouriadebf5c2021-01-05 12:57:36 -08002074TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
2075 EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
2076}
2077
2078TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002079 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002080
2081 auto surfaceFrame1 =
2082 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002083 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2084 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002085 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2086 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2087 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2088 presentFence1->signalForTest(oneHundredMs);
2089 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2090
2091 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2092}
2093
2094TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002095 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2096 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002097 auto surfaceFrame1 =
2098 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002099 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2100 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002101 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2102 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2103 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2104 presentFence1->signalForTest(oneHundredMs);
2105 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2106
2107 auto surfaceFrame2 =
2108 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002109 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2110 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002111 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2112 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2113 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2114 presentFence2->signalForTest(twoHundredMs);
2115 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2116
2117 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 10.0);
2118}
2119
2120TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002121 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2122 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002123 auto surfaceFrame1 =
2124 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002125 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2126 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002127 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2128 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2129 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2130 presentFence1->signalForTest(oneHundredMs);
2131 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2132
2133 auto surfaceFrame2 =
2134 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002135 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
2136 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002137 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2138 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2139 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2140 presentFence2->signalForTest(twoHundredMs);
2141 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2142
2143 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne, sLayerIdTwo}), 10.0f);
2144}
2145
2146TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002147 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2148 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002149 auto surfaceFrame1 =
2150 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002151 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2152 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002153 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2154 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2155 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2156 presentFence1->signalForTest(oneHundredMs);
2157 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2158
2159 auto surfaceFrame2 =
2160 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002161 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
2162 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002163 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2164 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2165 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2166 presentFence2->signalForTest(twoHundredMs);
2167 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2168
2169 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 0.0f);
2170}
2171
2172TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
Adithya Srinivasan939cd4d2021-02-23 06:18:13 +00002173 const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
2174 const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
2175 const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
2176 const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
2177 const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
Alec Mouriadebf5c2021-01-05 12:57:36 -08002178 auto surfaceFrame1 =
2179 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002180 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2181 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002182 auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2183 surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
2184 mFrameTimeline->addSurfaceFrame(surfaceFrame1);
2185 presentFence1->signalForTest(oneHundredMs);
2186 mFrameTimeline->setSfPresent(oneHundredMs, presentFence1);
2187
2188 auto surfaceFrame2 =
2189 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002190 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2191 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002192 auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2193 surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
2194 mFrameTimeline->addSurfaceFrame(surfaceFrame2);
2195 presentFence2->signalForTest(twoHundredMs);
2196 mFrameTimeline->setSfPresent(twoHundredMs, presentFence2);
2197
2198 auto surfaceFrame3 =
2199 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002200 sLayerIdTwo, sLayerNameTwo, sLayerNameTwo,
2201 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002202 auto presentFence3 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2203 surfaceFrame3->setPresentState(SurfaceFrame::PresentState::Presented);
2204 mFrameTimeline->addSurfaceFrame(surfaceFrame3);
2205 presentFence3->signalForTest(threeHundredMs);
2206 mFrameTimeline->setSfPresent(threeHundredMs, presentFence3);
2207
2208 auto surfaceFrame4 =
2209 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002210 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2211 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002212 auto presentFence4 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2213 surfaceFrame4->setPresentState(SurfaceFrame::PresentState::Presented);
2214 mFrameTimeline->addSurfaceFrame(surfaceFrame4);
2215 presentFence4->signalForTest(fiveHundredMs);
2216 mFrameTimeline->setSfPresent(fiveHundredMs, presentFence4);
2217
2218 auto surfaceFrame5 =
2219 mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
Adithya Srinivasan785addd2021-03-09 00:38:00 +00002220 sLayerIdOne, sLayerNameOne, sLayerNameOne,
2221 /*isBuffer*/ true);
Alec Mouriadebf5c2021-01-05 12:57:36 -08002222 auto presentFence5 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
2223 // Dropped frames will be excluded from fps computation
2224 surfaceFrame5->setPresentState(SurfaceFrame::PresentState::Dropped);
2225 mFrameTimeline->addSurfaceFrame(surfaceFrame5);
2226 presentFence5->signalForTest(sixHundredMs);
2227 mFrameTimeline->setSfPresent(sixHundredMs, presentFence5);
2228
2229 EXPECT_EQ(mFrameTimeline->computeFps({sLayerIdOne}), 5.0f);
2230}
2231
Adithya Srinivasanf279e042020-08-17 14:56:27 -07002232} // namespace android::frametimeline